(function (global, factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        module.exports = global.document ? factory(global, true) : function (w) {
            if (!w.document) {
                throw new Error("fzisCm7 requires a window with a document");
            }
            return factory(w);
        }
    } else {
        factory(global);
    }
}(typeof window !== "undefined" ? window : this, function (window, noGlobal) {
    var version = "1.0",
        __g, _skyboxPath, __rootId = '11111111-1111-1111-1111-111111111111',
        _cmData, _onImageButtonClickFunc, _originScene, jsDir = getMyPath(),
        cm7 = function (id, is3d) {
            return new cm7.fn.initJs(id, is3d);
        };
    cm7.fn = cm7.prototype = {
        constructor: cm7,
        version: function () {
            return 'fzisCm7 v1.0';
        },
        init: function (isTouch, skyboxPath) {
            try {
                var lic = __g.new_LicenseServer;
                if (lic.enableTrial) //7.1的ComServer无此属性
                    lic.enableTrial();
                if (!__g.project.create(null)) {
                    alert("create project failed!");
                    return false;
                }
                __g.camera.flyTime = 1;
                return true;
            } catch (ex) {
                alert(ex.message);
                return false;
            }
        },
    };
    cm7.fn.initJs = function (id, isDiv) {
        var ele = document.getElementById(id);
        __g = ele;
        if (isDiv === true) {
            var myid = '__g' + Math.round(Math.random() * 1000),
                obj = document.createElement('object');
            obj.setAttribute('id', myid);
            obj.setAttribute('type', 'application/x-cm-3d');
            obj.setAttribute('style', 'height:100%;width:100%');
            ele.appendChild(obj);
            __g = document.getElementById(myid);
        }
        _cmData = new CmData();
        cm7.ClearHelper = new ClearHelper();
        return this;
    };
    cm7.fn.initJs.prototype = cm7.fn;
    cm7.extend = cm7.fn.extend = function () {
        var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {},
            i = 1,
            length = arguments.length,
            deep = false;
        if (typeof target === "boolean") {
            deep = target;
            target = arguments[i] || {};
            i++;
        }
        if (typeof target !== "object" && !cm7.isFunction(target)) {
            target = {};
        }
        if (i === length) {
            target = this;
            i--
        }
        for (; i < length; i++) {
            if ((options = arguments[i]) != null) {
                for (name in options) {
                    src = target[name];
                    copy = options[name];
                    if (target === copy) {
                        continue
                    }
                    if (deep && copy && (cm7.isPlainObject(copy) || (copyIsArray = cm7.isArray(copy)))) {
                        if (copyIsArray) {
                            copyIsArray = false;
                            clone = src && cm7.isArray(src) ? src : [];
                        } else {
                            clone = src && cm7.isPlainObject(src) ? src : {};
                        }
                        target[name] = cm7.extend(deep, clone, copy)
                    } else if (copy !== undefined) {
                        target[name] = copy;
                    }
                }
            }
        }
        return target;
    };

    function getMyPath() {
        var scriptSrc = document.getElementsByTagName('script')[document.getElementsByTagName('script').length - 1].src;
        var jsName = scriptSrc.split('/')[scriptSrc.split('/').length - 1];
        return scriptSrc.replace(jsName, '').replace('file:///', '');
    }

    function exceptionHandler(e) {
        var msg = (typeof e == "object") ? e.message : e;
        alert(msg);
        var code = parseInt(msg.substring(msg.indexOf("[") + 1, msg.length - 1));
        if (code == -2147220504) {
            alert("此类型的数据源不支持此操作!");
        }
    }

    var class2type = {};
    var toString = class2type.toString;
    var hasOwn = class2type.hasOwnProperty;
    var getProto = Object.getPrototypeOf;
    var fnToString = hasOwn.toString;
    var ObjectFunctionString = fnToString.call(Object);
    cm7.extend({
        expando: "fzisCm7_" + (version + Math.random()).replace(/\D/g, ""),
        error: function (msg) {
            throw new Error(msg);
        },
        isArray: Array.isArray,
        isWindow: function (obj) {
            return obj != null && obj === obj.window
        },
        isNumeric: function (obj) {
            return !cm7.isArray(obj) && (obj - parseFloat(obj) + 1) >= 0
        },
        isEmptyObject: function (obj) {
            var name;
            for (name in obj) {
                return false;
            }
            return true;
        },
        isNull: function (obj) {
            if (typeof(obj) != 'undefined' && typeof(obj) != 'null') {
                return false;
            } else {
                return true;
            }
        },
        inArray: function (elem, arr, i) {
            return arr == null ? -1 : indexOf.call(arr, elem, i);
        },
        isPlainObject: function (obj) {
            var proto, Ctor;
            if (!obj || toString.call(obj) !== "[object Object]") {
                return false
            }
            proto = getProto(obj);
            if (!proto) {
                return true;
            }
            Ctor = class2type.hasOwnProperty.call(proto, "constructor") && proto.constructor;
            return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
        },
        guid: 1,
        now: Date.now,
        getRootPath: function () {
            var abspath = unescape(window.location.href);
            var index = abspath.indexOf("?");
            if (index > 0) abspath = abspath.substr(0, index - 1);
            index = abspath.lastIndexOf("/");
            var index2 = abspath.lastIndexOf("\\");
            index = (index > index2) ? index : index2;
            if (index <= 0) return abspath;
            abspath = abspath.substring(0, index);
            if (abspath.substring(0, 1) == "/") abspath = abspath.slice(1);
            var re = /file:\/\/\//gi;
            if (abspath.match(re) != null) abspath = abspath.replace(re, "");
            return abspath;
        },
        getRealPath: function () {
            var rootFilePath = document.location.pathname;
            var rootArr = rootFilePath.split('/');
            var rootPath = "";
            for (var i = 1; i < rootArr.length - 1; i++) {
                rootPath += rootArr[i] + "/"
            }
            return rootPath;
        },
        getJsDir: function () {
            return jsDir;
        },
    });

    function m_skyBox(i, basePath, fix) {
        var skyboxObj = __g.objectManager.getSkyBox(i);
        var sb = cm7Enum.gviSkyboxImageIndex;
        basePath += fix;
        skyboxObj.setImagePath(sb.gviSkyboxImageBack, basePath + "_BK.jpg");
        console.log(basePath + "_BK.jpg");
        skyboxObj.setImagePath(sb.gviSkyboxImageBottom, basePath + "_DN.jpg");
        skyboxObj.setImagePath(sb.gviSkyboxImageFront, basePath + "_FR.jpg");
        skyboxObj.setImagePath(sb.gviSkyboxImageLeft, basePath + "_LF.jpg");
        skyboxObj.setImagePath(sb.gviSkyboxImageRight, basePath + "_RT.jpg");
        skyboxObj.setImagePath(sb.gviSkyboxImageTop, basePath + "_UP.jpg")
    }

    cm7.extend({
        getg: function () {
            return __g;
        },
        getCmData: function () {
            return _cmData;
        },
        panMove: function () {
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
            __g.measurementMode = -1;
        },
        isOpenSnap: function (isOpen) {
            if (!cm7.isNull(isOpen)) {
                if (isOpen) {
                    __g.MouseSnapMode = cm7Enum.gviMouseSnapMode.gviMouseSnapVertex;
                } else {
                    __g.MouseSnapMode = cm7Enum.gviMouseSnapMode.gviMouseSnapDisable;
                }
            }

            return __g.MouseSnapMode === cm7Enum.gviMouseSnapMode.gviMouseSnapVertex;
        },
        terrainAreaMeasure: function () {
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractMeasurement;
            __g.measurementMode = cm7Enum.gviMeasurementMode.gviMeasureGroundArea;
        },
        projectionAreaMeasure: function () {
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractMeasurement;
            __g.measurementMode = cm7Enum.gviMeasurementMode.gviMeasureArea;
        },
        horizontalMeasure: function () {
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractMeasurement;
            __g.measurementMode = cm7Enum.gviMeasurementMode.gviMeasureHorizontalDistance;
        },
        verticalMeasure: function () {
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractMeasurement;
            __g.measurementMode = cm7Enum.gviMeasurementMode.gviMeasureVerticalDistance;
        },
        aerialMeasure: function () {
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractMeasurement;
            __g.measurementMode = cm7Enum.gviMeasurementMode.gviMeasureAerialDistance;
        },
        terrainDistanceMeasure: function () {
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractMeasurement;
            __g.measurementMode = cm7Enum.gviMeasurementMode.gviMeasureGroundDistance;
        },
        pickCoordinate: function () {
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractMeasurement;
            __g.measurementMode = cm7Enum.gviMeasurementMode.gviMeasureCoordinate;
        },
        terrainSightLine: function () {
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractMeasurement;
            __g.measurementMode = cm7Enum.gviMeasurementMode.gviMeasureGroupSightLine;
        },
        walkMode: function () {
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractWalk;
            __g.camera.walkSpeed = 15;
        },
        walkMode2: function () {
            __g.Camera.WalkMode = cm7Enum.gviWalkMode.gviWalkOnAll;
        },
        pauseRendering: function () {
            __g.pauseRendering(false)
        },
        resumeRendering: function () {
            __g.resumeRendering();
        },
        setWeather: function (gviWeatherType, skyboxIndex) {
            var skyboxObj = __g.objectManager.getSkyBox(skyboxIndex);
            skyboxObj.weather = gviWeatherType;
        },
        setAllSkyBoxWeather: function (gviWeatherType) {
            for (var i = 0; i < 4; i++) {
                cm7.setWeather(gviWeatherType, i);
            }
        },
        cameraUndo: function () {
            __g.camera.undo();
        },
        cameraRedo: function () {
            __g.camera.redo();
        },
        topView: function () {
            var c = cm7.cameraPos();
            c.tilt = -90;
            cm7.cameraPos(c);
        },
        lookAround: function () {
            var c = cm7.cameraPos();
            c.heading += 180;
            cm7.cameraPos(c);
        },
        cameraFlyTime: function (num) {
            if (typeof(num) != 'undefined' && typeof(num) != 'null') {
                __g.camera.flyTime = num
            }
            return __g.camera.flyTime
        },
        toggleShowDEM: function () {
            __g.terrain.demAvailable = !__g.terrain.demAvailable
        },
        isShowDEM: function (isShow) {
            if (typeof(isShow) != 'undefined' && typeof(isShow) != 'null') {
                __g.terrain.demAvailable = isShow
            }
            return __g.terrain.demAvailable
        },
        toggleShowTerrain: function () {
            if (__g.terrain.visibleMask === cm7Enum.gviViewportMask.gviViewNone) {
                __g.terrain.visibleMask = cm7Enum.gviViewportMask.gviViewAllNormalView
            } else {
                __g.terrain.visibleMask = cm7Enum.gviViewportMask.gviViewNone
            }
        },
        isShowTerrain: function (isShow) {
            if (typeof(isShow) != 'undefined' && typeof(isShow) != 'null') {
                if (isShow) {
                    __g.terrain.visibleMask = cm7Enum.gviViewportMask.gviViewAllNormalView
                } else {
                    __g.terrain.visibleMask = cm7Enum.gviViewportMask.gviViewNone
                }
            }
            return __g.terrain.visibleMask !== cm7Enum.gviViewportMask.gviViewNone
        },
        getWkt: function () {
            return __g.terrain.wkt
        },
        terrainOpacity: function (num) {
            if (typeof(num) != 'undefined' && typeof(num) != 'null') {
                __g.terrain.opacity = num;
                return num;
            }
            return __g.terrain.opacity
        },
        toggleFullScreen: function () {
            __g.fullScreen = !__g.fullScreen;
        },
        fullScreen: function (isFull) {
            if (typeof(isFull) != 'undefined' && typeof(isFull) != 'null') {
                return __g.fullScreen = isFull;
            }
            return __g.fullScreen;
        },
        newVector3: function (x, y, z) {
            var v3 = __g.new_Vector3;
            v3.set(x, y, z);
            return v3;
        },
        newAngle: function (heading, tilt, roll) {
            var eulerAngle = __g.new_EulerAngle;
            eulerAngle.set(heading, tilt, roll);
            return eulerAngle;
        },
        changeSkyBox: function (index, skyBoxIndex) {
            var skyboxObj = __g.objectManager.getSkyBox(skyBoxIndex);
            var skyboxImg = cm7Enum.gviSkyboxImageIndex;
            // index = 1;
            // skyBoxIndex=0;
            // console.log(index);
            switch (index) {
                case 0:
                    m_skyBox(skyBoxIndex, _skyboxPath, '00');
                    break;
                case 1:
                    m_skyBox(skyBoxIndex, _skyboxPath, '1');
                    break;
                case 2:
                    m_skyBox(skyBoxIndex, _skyboxPath, '2');
                    break;
                case 3:
                    m_skyBox(skyBoxIndex, _skyboxPath, '04');
                    break;
                case 4:
                    m_skyBox(skyBoxIndex, _skyboxPath, '7');
                    break;
                case 5:
                    m_skyBox(skyBoxIndex, _skyboxPath, '9');
                    break;
                case 6:
                    m_skyBox(skyBoxIndex, _skyboxPath, '10');
                    break;
                case 7:
                    m_skyBox(skyBoxIndex, _skyboxPath, '11');
                    break;
                case 8:
                    m_skyBox(skyBoxIndex, _skyboxPath, '12');
                    break;
                case 9:
                    m_skyBox(skyBoxIndex, _skyboxPath, '13');
                    break;
                case 10:
                    m_skyBox(skyBoxIndex, _skyboxPath, '22');
                    break;
                case 11:
                    m_skyBox(skyBoxIndex, _skyboxPath, '44');
                    break;
                case 12:
                    m_skyBox(skyBoxIndex, _skyboxPath, '99');
                    break;
                case 13:
                    m_skyBox(skyBoxIndex, _skyboxPath, '100');
                    break;
                case 14:
                    m_skyBox(skyBoxIndex, _skyboxPath, '120');
                    break;
                case 15:
                    m_skyBox(skyBoxIndex, _skyboxPath, '130');
                    break;
                default:
                    m_skyBox(skyBoxIndex, _skyboxPath, '130');
                    break
            }
        },
        changeAllSkyBox: function (index) {
            for (var i = 0; i < 4; i++) {
                cm7.changeSkyBox(index, i);
            }
        },

        getFeaturesInRegion: function (allFeatureClasses, polygon) {
            var self = this;
            var g = __g;
            g.featureManager.unhighlightAll();
            var cursor = null;
            var row = null;
            var resultRow = null;
            var resultFc = null;
            self.searchResult = [];

            for (var item in allFeatureClasses) {
                var fc = allFeatureClasses[item];
                var filter = g.new_SpatialFilter;
                filter.geometry = polygon;
                filter.spatialRel = cm7Enum.gviSpatialRel.gviSpatialRelIntersects;
                filter.geometryField = "Geometry";
                cursor = fc.obj.search(filter, false);

                while ((row = cursor.nextRow()) != null) {
                    self.searchResult.push({
                        fc: fc,
                        row: row,
                    });
                }
            }
            return self.searchResult
        },
    });

    function fnOnUIWindowEvent(sender, e) {
        if (sender.uiWindow == null) return;
        if (e === cm7Enum.gviUIEventType.gviUIMouseClick) {
            if (sender.uiWindow.type === cm7Enum.gviUIWindowType.gviUIImageButton) {
                if (_onImageButtonClickFunc != null) {
                    _onImageButtonClickFunc(sender, e, sender.uiWindow.name);
                }
            }
        }
    }

    var _isBsFull = false;
    cm7.extend({
        cameraPos: function (c) {
            if (!cm7.isNull(c)) {
                var vt = cm7.newVector3(c.x, c.y, c.z);
                var angle = cm7.newAngle(c.heading, c.tilt, c.roll);
                __g.camera.setCamera(vt, angle, cm7Enum.gviSetCameraFlags.gviSetCameraNoFlags);
                return c
            } else {
                var ca = __g.camera.getCamera();
                return {
                    "x": ca.position.x,
                    "y": ca.position.y,
                    "z": ca.position.z,
                    "heading": ca.angle.heading,
                    "tilt": ca.angle.tilt,
                    "roll": ca.angle.roll
                }
            }
        },
        cameraLookAt: function (pos, distance, angle) {
            __g.camera.lookAt(pos, distance, angle)
        },
        getOriginScene: function () {
            return _originScene;
        },
        flyToLayer: function (fl, distance) {
            var env = fl.envelope;
            if (env.maxX == 0.0 && env.maxY == 0.0 && env.maxZ == 0.0 && env.minX == 0.0 && env.minY == 0.0 && env.minZ == 0.0) {
                return null
            }
            var pos = __g.new_Vector3;
            var ang = __g.new_EulerAngle;
            pos.set((env.maxX + env.minX) / 2, (env.maxY + env.minY) / 2, (env.maxZ + env.minZ) / 2);
            ang.heading = 0;
            ang.tilt = -20;
            var ret = {
                position: pos,
                distance: distance,
                angle: ang
            };
            __g.camera.lookAt(pos, distance, ang);
            return ret
        },
        isLayerShow: function (layer, isShow) {
            if (!cm7.isNull(isShow)) {
                if (isShow) {
                    layer.visibleMask = cm7Enum.gviViewportMask.gviViewAllNormalView
                } else {
                    layer.visibleMask = cm7Enum.gviViewportMask.gviViewNone
                }
            }
            return layer.visibleMask !== cm7Enum.gviViewportMask.gviViewNone
        },
        browserFullScreen: function (isFull) {
            if (isFull) {
                var docElm = document.documentElement;
                if (docElm.requestFullscreen) {
                    docElm.requestFullscreen()
                } else if (docElm.mozRequestFullScreen) {
                    docElm.mozRequestFullScreen()
                } else if (docElm.webkitRequestFullScreen) {
                    docElm.webkitRequestFullScreen()
                } else if (docElm.msRequestFullscreen) {
                    // var  wscript = new ActiveXObject("WScript.Shell");
                    // if(wscript){
                    //     wscript.SendKeys("{F11}");
                    // }
                    docElm.msRequestFullscreen();
                }
            } else {
                if (document.exitFullscreen) {
                    document.exitFullscreen()
                } else if (document.mozCancelFullScreen) {
                    document.mozCancelFullScreen()
                } else if (document.webkitCancelFullScreen) {
                    document.webkitCancelFullScreen()
                } else if (document.msExitFullscreen) {
                    // var  wscript = new ActiveXObject("WScript.Shell");
                    // if(wscript){
                    //     wscript.SendKeys("{F11}");
                    // }
                    document.msExitFullscreen();
                }
            }
        },
        browserFullScreenSwitch: function () {
            if (_isBsFull) {
                __g.fullScreen = false;
                // cm7.browserFullScreen(false);
                _isBsFull = false
            } else {
                __g.fullScreen = true;
                // cm7.browserFullScreen(true);
                _isBsFull = true
            }
        },
        unhighlightAll: function () {
            __g.featureManager.unhighlightAll()
        },
        highlightFeature: function (fcObj, fid, color) {
            if (typeof(color) == 'undefined') {
                color = 0xffff00ff
            }
            __g.featureManager.highlightFeature(fcObj, fid, color)
        },
        highlightJson: function (modelJson, color) {
            if (typeof(color) == 'undefined') {
                color = 0xffff00ff
            }
            if (modelJson.length && modelJson.length > 0) {
                for (var i = 0; i < modelJson.length; i++) {
                    var mj = modelJson[i];
                    cm7.highlightFeature(mj.fcObj, mj.oid, color)
                }
            } else {
                cm7.highlightFeature(modelJson.fcObj, modelJson.oid, color)
            }
        },
        flyToFeature: function (modelJson, color) {
            var fcObj = modelJson.fcObj,
                geometry = modelJson.Geometry,
                envelope = geometry.envelope,
                objId = modelJson[fcObj.fidFieldName],
                angle = cm7.newAngle(0, -30, 0),
                distance = 300;
            // var symbol = __g.new_ModelPointSymbol;
            // symbol.setResourceDataSet(fcObj.featureDataSet);
            // var rmp = __g.objectManager.createRenderModelPoint(geometry, symbol, '');
            // if (rmp != null) {
            //     __g.camera.flyToObject(rmp.guid, cm7Enum.gviActionCode.gviActionJump);
            //     rmp.glow(2000);
            //     __g.objectManager.delayDelete(rmp.guid, 2000)
            // }
            __g.camera.lookAtEnvelope(envelope);
        },
        flyToLinePoint: function (p1, p2) {
            if (p1.x != '' && p1.y != '' && p1.z != '' && p2.x != '' && p2.y != '' && p2.z != '') {
                var pos1 = cm7.newVector3(p1.x, p1.y, p1.z),
                    pos2 = cm7.newVector3(p2.x, p2.y, p2.z),
                    angle = __g.camera.getAimingAngles(pos1, pos2);
                __g.camera.lookAt(pos1, 0, angle)
            }
        },
        createImageButton: function (normalImage, hoverImage, left, top, w, h, name, isShow) {
            try {
                var btn = __g.uiWindowManager.createImageButton();
                btn.isVisible = true;
                if (typeof(isShow) == "undefined") {
                    btn.isVisible = true
                } else if (isShow == false) {
                    btn.isVisible = false
                }
                setImageButtonArea(btn, left, top, w, h);
                btn.name = name;
                btn.text = name;
                btn.normalImage = normalImage;
                btn.hoverImage = hoverImage;
                btn.pushedImage = hoverImage;
                btn.disabledImage = hoverImage;
                btn.subscribeEvent(cm7Enum.gviUIEventType.gviUIMouseClick);
                if (__g.onuiwindowevent == null) {
                    __g.onuiwindowevent = fnOnUIWindowEvent
                }
                return btn
            } catch (e) {
                console.error(e.message)
            }
        },
        onImageButtonClick: function (func) {
            _onImageButtonClickFunc = func
        },
        setImageButtonArea: function (button, left, top, w, h) {
            if (button == null) {
                return
            }
            var rect = __g.new_UIRect;
            rect.init(0, left, 0, top, 0, left + w, 0, top + h);
            button.setArea(rect)
        },
        getModel: function (fcObj, geo) {
            if (geo.geometryType !== cm7Enum.gviGeometryType.gviGeometryModelPoint) {
                return null;
            }
            return fcObj.featureDataSet.getModel(geo.modelName);
        }
    });

    function read3dData(c, name, textRender, geoRender) {
        try {
            var ds = __g.dataSourceFactory.openDataSource(c);
            if (!name) {
                name = ds.guid
            }
            var fdbData = {
                'name': name,
                'dataSource': ds,
                'conn': c,
                'childs': []
            };
            var fdsNames = ds.getFeatureDatasetNames();
            if (fdsNames.length === 0) {
                return false
            }
            for (var j = 0; j < fdsNames.length; j++) {
                var fds = ds.openFeatureDataset(fdsNames[j]);
                var fcNames = fds.getNamesByType(cm7Enum.gviDataSetType.gviDataSetFeatureClassTable);
                // if (fcNames.length === 0) {
                //     continue;
                // }
                var dataSetData = {
                    'name': fdsNames[j],
                    'obj': fds,
                    'childs': []
                };
                for (var i = 0; i < fcNames.length; i++) {
                    var fcObj = fds.openFeatureClass(fcNames[i]);
                    var fc = new FC({
                        'name': fcNames[i],
                        'obj': fcObj,
                        'layer': null
                    });
                    dataSetData.childs.push(fc)
                }
                fdbData.childs.push(dataSetData)
            }
            _cmData.addData(fdbData)
        } catch (e) {
            exceptionHandler(e)
        }
    }

    function CmData() {
        this.cmData = []
    }

    CmData.prototype = {
        constructor: CmData,
        getSpatialCRS: function () {
            var self = this;
            if (self.cmData && self.cmData.length > 0) {
                var fdbData = self.cmData[0];
                if (fdbData.childs && fdbData.childs.length > 0) {
                    var dataSet = fdbData.childs[0];
                    var crs = dataSet.obj.spatialReference;
                    return crs
                }
            }
            return null
        },
        getAllData: function () {
            return this.cmData
        },
        addData: function (data) {
            this.cmData.push(data)
        },
        getFdbData: function (fdbName) {
            var self = this;
            for (var i = 0; i < self.cmData.length; i++) {
                if (self.cmData[i].name == fdbName) {
                    return self.cmData[i]
                }
            }
        },
        getFdbNames: function () {
            var self = this;
            var arr = [];
            for (var i = 0; i < self.cmData.length; i++) {
                arr[i] = self.cmData[i].name
            }
            return arr
        },
        getDatasetData: function (fdbName, dataSetName) {
            var self = this;
            var fdbData = self.getFdbData(fdbName);
            for (var i = 0; i < fdbData.childs.length; i++) {
                if (fdbData.childs[i].name == dataSetName) {
                    return fdbData.childs[i]
                }
            }
        },
        getDatasetNames: function (fdbName) {
            var self = this;
            var arr = [];
            var fdbData = self.getFdbData(fdbName);
            if (fdbData == null) {
                console.log(fdbName, 'is null');
                return [];
            }
            for (var i = 0; i < fdbData.childs.length; i++) {
                arr[i] = fdbData.childs[i].name
            }
            return arr
        },
        getFeatureClassNames: function (fdbName, dataSetName) {
            var self = this;
            var arr = [];
            var dataset = self.getDatasetData(fdbName, dataSetName);
            if (dataset != undefined) {
                for (var i = 0; i < dataset.childs.length; i++) {
                    arr[i] = dataset.childs[i].name
                }
            }
            return arr
        },
        getDatasetByGuid: function (guid) {
            var self = this;
            var ret = [];
            for (var i = 0; i < self.cmData.length; i++) {
                var fdbData = self.cmData[i];
                for (var j = 0; j < fdbData.childs.length; j++) {
                    var dsData = fdbData.childs[j];
                    if (dsData.obj.guid === guid) {
                        return dsData;
                    }
                }
            }
            return ret
        },
        getFeatureClassData: function (fdbName, dataSetName, fcName) {
            var self = this;
            var dataset = self.getDatasetData(fdbName, dataSetName);
            if (dataset != undefined) {
                for (var i = 0; i < dataset.childs.length; i++) {
                    if (dataset.childs[i].name === fcName) {
                        return dataset.childs[i]
                    }
                }
            }
        },
        getAllFeatureClass: function (nameFilter) {
            var self = this;
            var ret = [];
            for (var i = 0; i < self.cmData.length; i++) {
                var fdbData = self.cmData[i];
                for (var j = 0; j < fdbData.childs.length; j++) {
                    var dsData = fdbData.childs[j];
                    for (var m = 0; m < dsData.childs.length; m++) {
                        if (nameFilter == null) {
                            ret.push(dsData.childs[m])
                        } else {
                            if (nameFilter === dsData.childs[m].name) {
                                ret.push(dsData.childs[m])
                            }
                        }
                    }
                }
            }
            return ret
        },
        getAllFeatureClassObj: function (nameFilter) {
            var fcArray = this.getAllFeatureClass(nameFilter),
                fcObjs = [];
            fcArray.forEach(function (value, index, array) {
                fcObjs[index] = value.obj
            });
            return fcObjs
        },
        getDsAllChildFc: function (fdbName, dataSetName) {
            var ret = [];
            var ds = this.getDatasetData(fdbName, dataSetName);
            for (var i = 0; i < ds.childs.length; i++) {
                ret.push(ds.childs[i])
            }
            return ret;
        },
        getFCByPath: function (path) {
            var pm = path.split('/');
            return this.getFeatureClassData(pm[0], pm[1], pm[2])
        },
        getFeatureClassByGUID: function (guid) {
            var self = this;
            var fcArray = [];
            for (var i = 0; i < self.cmData.length; i++) {
                var fdbData = self.cmData[i];
                for (var j = 0; j < fdbData.childs.length; j++) {
                    var dsData = fdbData.childs[j];
                    for (var m = 0; m < dsData.childs.length; m++) {
                        if (dsData.childs[m].obj.guid === guid) {
                            return dsData.childs[m]
                        }
                    }
                }
            }
            return null
        },
        search: function (searchTxt, fcObjs) {
            var pattern = new RegExp(searchTxt);
            var ret = [];
            try {
                cm7.pauseRendering();
                var cursor = null;
                for (var i = 0; i < fcObjs.length; i++) {
                    var fcObj = fcObjs[i];
                    cursor = fcObj.search(null, true);
                    if (cursor == null) {
                        continue;
                    }
                    var row = null;
                    var fcInfoCol = fcObj.getFields();
                    while ((row = cursor.nextRow()) != null) {
                        var json = {};
                        json.fcObj = fcObj;
                        var isMatch = -1;
                        for (var j = 0; j < fcInfoCol.count; j++) {
                            var val = row.getValue(j);
                            json[fcInfoCol.get(j).name] = val;
                            json["row"] = row;
                            if (isMatch === -1 && typeof(val) !== 'object') {
                                // isMatch = ('' + val).indexOf(searchTxt)
                                if (val.toString().match(pattern) != null) {
                                    isMatch = 1;
                                    json['name'] = val.toString();
                                }
                            }
                        }
                        if (isMatch !== -1) {
                            ret.push(json)
                        }
                    }
                    // cursor.releaseObject();
                    cursor = null
                }
                return ret
            } catch (ex) {
                return ret
            } finally {
                cm7.resumeRendering()
            }
        },
        getAllLayers: function () {
            var self = this,
                ret = [];
            for (var i = 0; i < self.cmData.length; i++) {
                var fdbData = self.cmData[i];
                for (var j = 0; j < fdbData.childs.length; j++) {
                    var dsData = fdbData.childs[j];
                    for (var m = 0; m < dsData.childs.length; m++) {
                        var fc = dsData.childs[m];
                        if (fc.layer) {
                            ret.push(fc.layer)
                        }
                    }
                }
            }
            return ret
        },
        getFdbLayer: function (fdbName) {
            var self = this,
                ret = [];
            for (var i = 0; i < self.cmData.length; i++) {
                var fdbData = self.cmData[i];
                if (fdbData.name == fdbName) {
                    for (var j = 0; j < fdbData.childs.length; j++) {
                        var dsData = fdbData.childs[j];
                        for (var m = 0; m < dsData.childs.length; m++) {
                            var fc = dsData.childs[m];
                            if (fc.layer) {
                                ret.push(fc.layer)
                            }
                        }
                    }
                }
            }
            return ret
        },
        getDatasetLayers: function (fdbName, dataSetName) {
            var self = this,
                ret = [];
            var dsData = self.getDatasetData(fdbName, dataSetName);
            if (dsData != undefined) {
                for (var m = 0; m < dsData.childs.length; m++) {
                    var fc = dsData.childs[m];
                    if (fc.layer) {
                        ret.push(fc.layer)
                    }
                }
            }
            return ret
        },
        getFeatureClassLayers: function (fdbName, dataSetName, fcName) {
            var fc = this.getFeatureClassData(fdbName, dataSetName, fcName);
            if (fc.layer) {
                return fc.layer
            }
        },
    };

    function FC(fc) {
        if (cm7.isNull(fc.obj)) {
            fc = _cmData.getFeatureClassByGUID(fc.guid)
        }
        this.name = fc.name;
        this.obj = fc.obj;
        this.childs = fc.childs;
        this.layer = fc.layer
    }

    FC.prototype = {
        constructor: FC,
        createFeatureLayer: function (isShow, textRender, geoRender) {
            if (this.layer) {
                return this.layer
            }
            var fc = this.obj;
            if (cm7.isNull(isShow)) {
                isShow = true
            }
            var fis = fc.getFields();
            for (var t = 0; t < fis.count; t++) {
                var fi = fis.get(t);
                if (fi && fi.geometryDef) {
                    var fl = __g.objectManager.createFeatureLayer(fc, fi.name, textRender, geoRender, __rootId);
                    cm7.isLayerShow(fl, isShow);
                    this.layer = fl;
                    return fl
                }
            }
            return null
        },
        rowToJson: function (row) {
            if (!row) {
                return null
            }
            var json = {};
            for (var j = 0; j < row.fieldCount; j++) {
                json[row.fields.get(j).name] = row.getValue(j)
            }
            return json
        },
        jsonToRow: function (rowJson) {
            if (!rowJson) {
                return null
            }
            var row = this.obj.createRowBuffer();
            for (var f in rowJson) {
                if (f === 'fcObj') {
                    continue;
                }
                var index = row.fieldIndex(f);
                row.setValue(rowJson[f], index);
            }
            return row;
        },
        getRowById: function (fid) {
            try {
                var fcObj = this.obj,
                    json = this.rowToJson(fcObj.getRow(fid));
                json.fcObj = fcObj;
                return json
            } catch (ex) {
                return null
            }
        },
        deleteRowById: function (fid, isDelRender) {
            if (cm7.isNull(isDelRender) || isDelRender) {
                __g.featureManager.deleteFeature(this.obj, fid);
            }
            return this.obj.deleteRow(fid)
        },
        query: function (filter) {
            var self = this,
                fcObj = self.obj,
                ret = [],
                rows = self.queryToRow(filter);
            for (var i = 0; i < rows.length; i++) {
                var json = self.rowToJson(rows[i]);
                json.fcObj = fcObj;
                ret.push(json)
            }
            return ret
        },
        insertRow: function (row) {
            var cursor = null;
            try {
                cursor = this.obj.insert();
                cursor.insertRow(row);
                return cursor.lastInsertId
            } catch (ex) {
                return -1
            } finally {
                if (cursor) {
                    // cursor.releaseObject();
                    cursor = null
                }
            }
        },
        insert: function (rowJson) {
            try {
                var fcObj = this.obj,
                    fields = fcObj.getFields();
                var rb = __g.rowBufferFactory.createRowBuffer(fields);
                for (var j = 0; j < fields.count; j++) {
                    var fieldName = fields.get(j).name;
                    if (fieldName === fcObj.fidFieldName) {
                        continue
                    }
                    var index = rb.fieldIndex(fieldName);
                    if (index !== -1) {
                        var value = rowJson[fieldName];
                        if (value) {
                            rb.setValue(index, value)
                        }
                    }
                }
                return this.insertRow(rb);

            } catch (ex) {
                return -1
            }
        },
        // updateRow(row, isExtent){
        //     var fcObj = this.obj,
        //         cursor = null;
        //     try {
        //         var fidName = fcObj.fidFieldName,
        //             fIndex = row.fieldIndex(fidName),
        //             fid = row.getValue(fIndex);
        //         if (!fid) {
        //             return false
        //         }
        //         var filter = __g.new_QueryFilter;
        //         filter.whereClause = fidName + '=' + fid;
        //         cursor = fcObj.update(filter);
        //         var fields = fcObj.getFields();
        //         var fdeRow = null;
        //         if ((fdeRow = cursor.nextRow()) != null) {
        //
        //              cursor.updateRow(fdeRow);
        //             return true
        //         }
        //         return false
        //     } catch (ex) {
        //         return false
        //     } finally {
        //         if (cursor) {
        //             cursor.releaseObject();
        //             cursor = null
        //         }
        //     }
        //     if (isExtent) {
        //         var g = 'Geometry';
        //         fcObj.updateExtent(g);
        //         fcObj.addSpatialIndex(fcObj.calculateDefaultGridIndex(g));
        //         fcObj.addRenderIndex(fc.calculateDefaultRenderIndex(g))
        //     }
        // },
        update: function (rowJson, isExtent) {
            var fcObj = this.obj,
                cursor = null;
            try {
                var fidName = fcObj.fidFieldName;
                var fid = rowJson[fidName];
                if (!fid) {
                    return false
                }
                var filter = __g.new_QueryFilter;
                filter.whereClause = fidName + '=' + rowJson[fidName];
                cursor = fcObj.update(filter);
                var fields = fcObj.getFields();
                var fdeRow = null;
                if ((fdeRow = cursor.nextRow()) != null) {
                    for (var j = 0; j < fields.count; j++) {
                        var fieldName = fields.get(j).name;
                        var index = fdeRow.fieldIndex(fieldName);
                        if (index !== -1) {
                            var value = rowJson[fieldName];
                            if (value) {
                                fdeRow.setValue(index, value)
                            }
                        }
                    }
                    cursor.updateRow(fdeRow);
                    return true
                }
                return false
            } catch (ex) {
                return false
            } finally {
                if (cursor) {
                    // cursor.releaseObject();
                    cursor = null
                }
            }
            if (isExtent) {
                var g = 'Geometry';
                fcObj.updateExtent(g);
                fcObj.addSpatialIndex(fcObj.calculateDefaultGridIndex(g));
                fcObj.addRenderIndex(fcObj.calculateDefaultRenderIndex(g));
            }
        },
        truncate: function () {
            this.obj.truncate()
        },
        queryToRow: function (filter) {
            try {
                if (filter) {
                    filter.postfixClause = "order by oid DESC"
                } else {
                    filter = null
                }
                var cursor = this.obj.search(filter, false);
                if (cursor == null) {
                    return []
                }
                var row = null;
                var ret = [];
                /*while ((row = cursor.nextRow()) != null) {
                    ret.push(row)
                }*/
                row = cursor.nextRow()
                while (row != null) {
                    ret.push(row);
                    row = cursor.nextRow();
                }
                return ret
            } catch (ex) {
                console.error(ex.Message);
                return []
            } finally {
                if (cursor) {
                    // cursor.releaseObject();
                    cursor = null
                }
            }
        },
        search: function (searchTxt) {
            var ret = [];
            try {
                var cursor = null;
                var fcObj = this.obj;
                cursor = fcObj.search(null, true);
                if (cursor == null) {
                    return ret
                }
                var row = null;
                var fcInfoCol = fcObj.getFields();
                while ((row = cursor.nextRow()) != null) {
                    var json = {};
                    json.fcObj = fcObj;
                    var isMatch = -1;
                    for (var j = 0; j < fcInfoCol.count; j++) {
                        var val = row.getValue(j);
                        json[fcInfoCol.get(j).name] = val;
                        if (isMatch === -1 && typeof(val) !== 'object') {
                            isMatch = ('' + val).indexOf(searchTxt)
                        }
                    }
                    if (isMatch !== -1) {
                        ret.push(json)
                    }
                }
                return ret
            } catch (ex) {
                return ret
            } finally {
                // cursor.releaseObject();
                cursor = null
            }
        }
    };
    cm7.FC = function (fc) {
        return new FC(fc)
    };

    function LYs(lys) {
        if (lys) {
            this.lys = lys
        } else {
            this.lys = []
        }
    }

    function FDS(ds) {
        if (ds.obj) {
            ds = _cmData.getDatasetData()
        }
    }

    FDS.prototype = {
        constructor: FDS,

    };


    LYs.prototype = {
        constructor: LYs,
        isLayerShow: function (bl) {
            var self = this;
            if (!cm7.isNull(bl)) {
                self.lys.forEach(function (val, i, arr) {
                    cm7.isLayerShow(val.layer, bl);
                    self.isShow = bl
                })
            }
            return self.isShow
        },
        getEnvelope: function () {
            var self = this,
                env = __g.new_Envelope;
            env.set(99999999999, -99999999999, 99999999999, -99999999999, 99999999999, -99999999999);
            self.lys.forEach(function (val, i, arr) {
                var e = val.layer.envelope;
                env.maxX = e.maxX > env.maxX ? e.maxX : env.maxX;
                env.maxY = e.maxY > env.maxY ? e.maxY : env.maxY;
                env.maxZ = e.maxZ > env.maxZ ? e.maxZ : env.maxZ;
                env.minX = e.minX < env.minX ? e.minX : env.minX;
                env.minY = e.minY < env.minY ? e.minY : env.minY;
                env.minZ = e.minZ < env.minZ ? e.minZ : env.minZ
            });
            return env
        },
        lookAt: function () {
            var angle = cm7.newAngle(0, -90, 0);
            __g.camera.lookAt(this.getEnvelope().center, 800, angle)
        }
    };

    function CmTag(node) {
        if (node) {
            this.init(node)
        }
    }

    CmTag.prototype = {
        constructor: CmTag,
        init: function (node) {
            var self = this;
            self.tagName = node.tagName;
            self.type = node.type;
            self.idShow = node.idShow;
            self.objData = node.objData;
            if (self.objData) {
                var lyArr = [];
                self.objData.forEach(function (val, i, arr) {
                    if (val.objType === 256) {
                        var fc = _cmData.getFCByPath(val.res),
                            fl = fc.createFeatureLayer(node.idShow);
                        lyArr.push({
                            layer: fl,
                            fc: fc,
                            info: val
                        })
                    }
                });
                self.ly = new LYs(lyArr)
            }
        },
        isLayerShow: function (isShow) {
            this.idShow = isShow;
            this.ly.isLayerShow(isShow)
        },
        getEnvelope: function () {
            this.envelope = this.ly.getEnvelope();
            return this.envelope
        },
        lookAt: function () {
            if (!this.envelope) {
                this.getEnvelope()
            }
            var angle = cm7.newAngle(0, -90, 0);
            __g.camera.lookAt(this.envelope.center, 800, angle)
        }
    };


    function LayerManager() {
        this.layerData = [];
        this.lyList = []
    }

    LayerManager.prototype = {
        constructor: LayerManager,
        initFromConfig: function (cfg) {
            var self = this;

            function loopConfig(lyChild) {
                lyChild.forEach(function (val, i, arr) {
                    if (val.cmTag) {
                        val.cmTag.tagName = val.text;
                        val.cmTag = new CmTag(val.cmTag);
                        if (val.cmTag.ly && val.cmTag.ly.lys) {
                            self.lyList = self.lyList.concat(val.cmTag.ly.lys)
                        }
                    }
                    if (val.nodes) {
                        loopConfig(val.nodes)
                    }
                })
            }

            loopConfig(cfg);
            this.layerData = cfg;
            return cfg
        },
        getNodeByPath: function (path) {
            var pArr = path.split('/'),
                node = null,
                ret = false,
                t = 0;

            function loopConfig(lyChild) {
                lyChild.forEach(function (val, i, arr) {
                    if (val.text === pArr[t]) {
                        if (t === pArr.length - 1) {
                            node = val;
                            return
                        } else {
                            if (val.nodes) {
                                t++;
                                loopConfig(val.nodes)
                            }
                        }
                    }
                })
            }

            loopConfig(this.layerData);
            return node
        },
        getNodeChildLY: function (chd) {
            var lys = [],
                ret = [];

            function loop(nodes) {
                nodes.forEach(function (val, i, arr) {
                    if (val.cmTag) {
                        if (val.cmTag.ly) {
                            lys.push(val.cmTag.ly)
                        }
                    }
                    if (val.nodes) {
                        loop(val.nodes)
                    }
                })
            }

            if (chd.cmTag && chd.cmTag.ly) {
                lys.push(chd.cmTag.ly)
            }
            if (chd.nodes) {
                loop(chd.nodes)
            }
            lys.forEach(function (v, i, a) {
                v.lys.forEach(function (v2, i2, a2) {
                    ret.push(v2)
                })
            });
            return ret
        },
        getLYbyFc: function (fcObj) {
            var ret = null;
            this.lyList.forEach(function (ly, i, arr) {
                if (ly.fc.obj.guid === fcObj.guid) {
                    ret = ly
                }
            });
            return ret
        },
        getLYbyFl: function (fl) {
            var ret = null;
            this.lyList.forEach(function (ly, i, arr) {
                if (ly.layer.guid === fl.guid) {
                    ret = ly
                }
            });
            return ret
        }
    };
    var _layerManager = null;
    cm7.LayerManager = function () {
        if (_layerManager) {
            return _layerManager
        } else {
            _layerManager = new LayerManager();
            return _layerManager
        }
    };


    cm7.extend({
        loadServer: function (c, name, textRender, geoRender) {
            if (c.database != '' && c.password != '') {
                return read3dData(c, name, textRender, geoRender)
            } else {
                console.log("数据库无法连接：" + name);
            }
        },
        loadFDB: function (filePath, name, textRender, geoRender) {
            if(filePath!=''){
                var c = __g.new_ConnectionInfo;
                c.connectionType = cm7Enum.gviConnectionType.gviConnectionFireBird2x;
                c.database = filePath;
                return read3dData(c, name, textRender, geoRender)
            }else {
                console.log("数据库无法连接：" + name);
            }
        },
        loadTed: function (filePath, textRender, geoRender) {
            __g.terrain.registerTerrain(filePath, "");
        }
    });

    function HtmlWindow(url, width, height, offsetX, offsetY, id, transparent, round) {
        this.url = url;
        this.width = width;
        this.height = height;
        this.offsetX = offsetX;
        this.offsetY = offsetY;
        this.id = id;
        this.transparent = transparent;
        this.round = round
    }

    HtmlWindow.prototype = {
        constructor: HtmlWindow,
        show: function () {
            try {
                var wp = __g.htmlWindow.createWindowParam();
                wp.position = cm7Enum.gviHTMLWindowPosition.gviWinPosUserDefined;
                wp.filePath = this.url;
                wp.sizeX = this.width;
                wp.sizeY = this.height;
                wp.offsetX = this.offsetX;
                wp.offsetY = this.offsetY;
                wp.hastitle = false;
                wp.isPopupWindow = false;
                wp.hideOnClick = false;
                wp.round = this.round;
                wp.resizable = false;
                wp.winId = this.id;
                wp.minButtonVisible = false;
                wp.closeButtonEnabled = false;
                wp.transparence = this.transparent;
                __g.htmlWindow.setWindowParam(wp)
            } catch (e) {
                exceptionHandler(e);
                return null
            }
        },
        hide: function (isClear) {
            try {
                if (isClear) {
                    var wp = __g.htmlWindow.getWindowParam(this.id);
                    wp.filePath = "about:blank";
                    __g.htmlWindow.setWindowParam(wp)
                }
                __g.htmlWindow.hideWindow(this.id)
            } catch (ex) {
                console.error(ex)
            }
        }
    };
    cm7.HtmlWindow = function () {
        return new HtmlWindow()
    };


    function CameraTourPlay() {
        this.cameraTour = null
    }

    CameraTourPlay.prototype = {
        constructor: CameraTourPlay,
        importFromXMLFile: function (xmlPath) {
            var self = this;
            var doc = new ActiveXObject("Microsoft.XMLDOM");
            doc.load(xmlPath);
            self.importFromStrXML(doc.xml)
        },
        importFromStrXML: function (strXml) {
            var self = this;
            self.cameraTour = __g.objectManager.createCameraTour(__rootId);
            self.cameraTour.fromXml(strXml)
        },
        play: function () {
            var self = this;
            if (self.cameraTour) {
                self.cameraTour.play()
            }
        },
        stop: function () {
            var self = this;
            if (self.cameraTour) {
                self.cameraTour.stop()
            }
        },
        pause: function () {
            var self = this;
            if (self.cameraTour) {
                self.cameraTour.pause()
            }
        },
        createTour: function () {
            var self = this;
            if (self.cameraTour) {
                __g.objectManager.deleteObject(self.cameraTour.guid);
                self.cameraTour = null
            }
            self.cameraTour = __g.objectManager.createCameraTour(__rootId)
        },
        addScreenWaypoint: function () {
            var ci = cm7.cameraPos();
            var vet = cm7.newVector3(ci.x, ci.y, ci.z);
            var angle = cm7.newAngle(ci.heading, ci.tilt, ci.roll);
            this.cameraTour.addWaypoint(vet, angle, 2, 1);

        },
        addWaypoint: function (pos, duration, gviCameraTourMode) {
            var self = this;
            var vet = cm7.newVector3(pos.x, pos.y, pos.z);
            var angle = cm7.newAngle(pos.heading, pos.tilt, pos.roll);
            self.cameraTour.addWaypoint(vet, angle, duration, gviCameraTourMode)
        },
        deleteWaypoint: function (index) {
            var self = this;
            if (self.cameraTour) {
                self.cameraTour.deleteWaypoint(index)
            }
        },
        modifyWaypoint: function (index, pos, duration, gviCameraTourMode) {
            var self = this;
            if (self.cameraTour) {
                var vet = cm7.newVector3(pos.x, pos.y, pos.z);
                var angle = cm7.newAngle(pos.heading, pos.tilt, pos.roll);
                self.cameraTour.modifyWaypoint(index, vet, angle, duration, gviCameraTourMode)
            }
        },
        insertWaypoint: function (index, pos, duration, gviCameraTourMode) {
            var self = this;
            if (self.cameraTour) {
                var vet = cm7.newVector3(pos.x, pos.y, pos.z);
                var angle = cm7.newAngle(pos.heading, pos.tilt, pos.roll);
                self.cameraTour.insertWaypoint(index, vet, angle, duration, gviCameraTourMode)
            }
        },
        exportAsXml: function () {
            var self = this;
            var strXml = '';
            if (self.cameraTour) {
                strXml = self.cameraTour.asXml()
            }
            return strXml
        },
        exportAsVideo: function (path, beginFunc, endFunc, exportingFunc) {
            var self = this;
            if (self.cameraTour && self.cameraTour.waypointsNumber > 2) {
                __g.onvideoexportbegin = beginFunc;
                __g.onvideoexportend = endFunc;
                __g.onvideoexporting = exportingFunc;
                self.cameraTour.exportVideo(path, 25)
            }
        },
        exportAsFramePictures: function (path) {
            var self = this;
            if (self.cameraTour && self.cameraTour.waypointsNumber > 2) {
                self.cameraTour.exportFrameSequence(path, 1024, 1024, 25)
            }
        }
    };
    cm7.CameraTourPlay = function () {
        return new CameraTourPlay()
    };


    function ProjectInfo(name, modelPath, coordinate, imgPath, isSelected) {
        this.name = name;
        this.modelPath = modelPath;
        this.coordinate = coordinate;
        this.imgPath = imgPath;
        this.isSelected = isSelected;
        this.modelGuid = null
    }

    ProjectInfo.prototype = {
        constructor: ProjectInfo,
        loadModel: function (gviViewIndex) {
            var self = this;
            var geoFactory = __g.geometryFactory;
            var modePoint = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryModelPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            modePoint.modelName = self.modelPath;
            modePoint.setCoords(self.coordinate.dx, self.coordinate.dy, self.coordinate.dz, 0, 0);
            var renderModelPoint = __g.objectManager.createRenderModelPoint(modePoint, null, __rootId);
            self.modelGuid = renderModelPoint.guid;
            switch (gviViewIndex) {
                case 0:
                    renderModelPoint.visibleMask = cm7Enum.gviViewportMask.gviView0;
                    break;
                case 1:
                    renderModelPoint.visibleMask = cm7Enum.gviViewportMask.gviView1;
                    break;
                case 2:
                    renderModelPoint.visibleMask = cm7Enum.gviViewportMask.gviView2;
                    break;
                case 4:
                    renderModelPoint.visibleMask = cm7Enum.gviViewportMask.gviView3;
                    break;
                default:
                    break
            }
            var pos = __g.new_Vector3;
            var ang = __g.new_EulerAngle;
            pos.set(self.coordinate.dx, self.coordinate.dy, self.coordinate.dz);
            ang.heading = 0;
            ang.tilt = -20;
            __g.camera.lookAt(pos, 300, ang)
        },
        unLoadModel: function () {
            var self = this;
            if (self.modelGuid != null) {
                __g.objectManager.deleteObject(self.modelGuid);
                self.modelGuid = null
            }
        },
        setLookAngle: function (lookAngle) {
            var self = this;
            var pos = __g.new_Vector3;
            var ang = __g.new_EulerAngle;
            pos.set(self.coordinate.dx, self.coordinate.dy, self.coordinate.dz);
            ang.heading = lookAngle;
            ang.tilt = -20;
            __g.camera.lookAt(pos, 300, ang)
        }
    };

    function ProjectCompare() {
        this.projectList = [];
        this.count = 0;
        this.modelDir = cm7.getRootPath() + "/Schemes/"
    }

    ProjectCompare.prototype = {
        constructor: ProjectCompare,
        indexOfProject: function (p) {
            var self = this;
            for (var i = 0; i < self.projectList.length; i++) {
                if (p == self.projectList[i]) {
                    return i
                }
            }
            return -1
        },
        indexOfProjectByName: function (name) {
            var self = this;
            for (var i = 0; i < self.projectList.length; i++) {
                if (name == self.projectList[i].name) {
                    return i
                }
            }
            return -1
        },
        addProject: function (p) {
            var self = this;
            if (self.indexOfProject(p) == -1) {
                self.projectList.push(p)
            }
        },
        initFromJsonPath: function (jsonPath) {
            var self = this;
            var basePath = cm7.getRootPath() + "/Schemes/";
            $.ajaxSettings.async = false;
            $.getJSON(jsonPath, function (data) {
                $.each(data, function (infoindex, info) {
                    var coord = {};
                    coord.dx = info["x"];
                    coord.dy = info["y"];
                    coord.dz = info["z"];
                    var pragramme = new ProjectInfo(info["name"], self.modelDir + info["modelPath"], coord, info["imgPath"], info["isSelected"]);
                    self.addProject(pragramme)
                })
            });
            $.ajaxSettings.async = true
        },
        initFromJson: function (jsonData) {
            jsonData.forEach(function (value, index, array) {
                var coord = {};
                coord.dx = value["x"];
                coord.dy = value["y"];
                coord.dz = value["z"];
                var pragramme = new ProjectInfo(value["name"], value["modelPath"], coord, value["imgPath"], value["isSelected"]);
                self.addProject(pragramme)
            })
        },
        getProjectSelect: function (name) {
            var index = this.indexOfProjectByName(name);
            return this.projectList[index].isSelected
        },
        setProjectSelect: function (name, value) {
            var index = this.indexOfProjectByName(name);
            this.projectList[index].isSelected = value
        },
        setSelectedLookAngle: function (lookAngle) {
            var self = this;
            for (var i = 0; i < self.projectList.length; i++) {
                if (self.projectList[i].isSelected == true) {
                    self.projectList[i].setLookAngle(lookAngle);
                    return
                }
            }
        },
        compare: function () {
            var self = this;
            var k = 0;
            for (var i = 0; i < self.projectList.length; i++) {
                self.projectList[i].unLoadModel();
                if (self.projectList[i].isSelected == true) {
                    self.projectList[i].loadModel(k);
                    k++
                }
            }
            switch (k) {
                case 0:
                    __g.viewport.viewportMode = cm7Enum.gviViewportMode.gviViewportSinglePerspective;
                    break;
                case 1:
                    __g.viewport.viewportMode = cm7Enum.gviViewportMode.gviViewportSinglePerspective;
                    break;
                case 2:
                    __g.viewport.viewportMode = cm7Enum.gviViewportMode.gviViewportL1R1;
                    break;
                case 3:
                    __g.viewport.viewportMode = cm7Enum.gviViewportMode.gviViewportL1M1R1;
                    break;
                case 4:
                    __g.viewport.viewportMode = cm7Enum.gviViewportMode.gviViewportQuad;
                    break
            }
            __g.viewport.cameraViewBindMask = cm7Enum.gviViewportMask.gviViewAllNormalView
        },
        endCompare: function () {
            var self = this;
            for (var i = 0; i < self.projectList.length; i++) {
                self.projectList[i].isSelected = false;
                self.projectList[i].unLoadModel()
            }
            __g.viewport.viewportMode = cm7Enum.gviViewportMode.gviViewportSinglePerspective
        }
    };
    cm7.ProjectCompare = function () {
        return new ProjectCompare()
    };


    function SightlineAnalysis(fcArray) {
        this.startPoint = null;
        this.endPoint = null;
        this.geo = null;
        this.renderPolyline = null;
        this.drawFirstPointFunc = null;
        this.drawLastPointFunc = null;
        this.barrierBuildingMap = [];
        this.fcArray = fcArray;
    }

    // 通视分析
    SightlineAnalysis.prototype = {
        constructor: SightlineAnalysis,
        setLine: function (startPoint, endPoint) {
            var self = this;
            self.startPoint = startPoint;
            self.endPoint = endPoint
        },
        drawLine: function () {
            var self = this;
            self.clearResult();
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractEdit;
            self.geo = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolyline, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            self.renderPolyline = __g.objectManager.createRenderPolyline(self.geo, null, __rootId);
            var resultCode = __g.objectEditor.startEditRenderGeometry(self.renderPolyline, cm7Enum.gviGeoEditType.gviGeoEditCreator);

            var EventCall = {
                onObjectEditing: function (geometry) {
                    self.geo = geometry;
                    if (geometry.pointCount === 1) {
                        if (self.drawFirstPointFunc != null) {
                            self.drawFirstPointFunc(self.geo.getPoint(0))
                        }
                    }
                    if (geometry.pointCount >= 2) {
                        self.finishEdit();
                        if (self.drawLastPointFunc != null) {
                            self.drawLastPointFunc(self.geo.getPoint(1))
                        }
                        __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
                        self.startPoint = self.geo.getPoint(0);
                        self.endPoint = self.geo.getPoint(1)
                    }
                },
                onObjectEditFinish: function () {
                    __g.callback.onObjectEditFinish = null;
                    __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
                }
            };
            __g.callback = EventCall;
        },
        finishEdit: function () {
            __g.objectEditor.finishEdit();
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal
        },
        sightAnalysis: function () {
            cm7.pauseRendering();
            var self = this;
            if (self.geo == null) {
                return
            }
            var geoFactory = __g.geometryFactory;
            try {
                cm7.unhighlightAll();
                self.barrierBuildingMap = [];
                var row = null;
                var index = 0;
                var filter = __g.new_SpatialFilter;
                filter.geometry = self.geo;
                filter.spatialRel = cm7Enum.gviSpatialRel.gviSpatialRelIntersects;
                filter.geometryField = "Geometry";

                for (var j = 0; j < self.fcArray.length; j++) {
                    var fc = self.fcArray[j];
                    var rows = fc.query(filter);
                    for (var k = 0; k < rows.length; k++) {
                        var row = rows[k];
                        if (row.hasOwnProperty("ObjTypeName") && row["ObjTypeName"] == "区域控高盒") {
                            continue;
                        }
                        var modelPoint = row.Geometry;
                        if (modelPoint.modelName) {
                            var model = fc.obj.featureDataSet.getModel(modelPoint.modelName);
                            var vector = cm7.newVector3(
                                self.endPoint.x - self.startPoint.x,
                                self.endPoint.y - self.startPoint.y,
                                self.endPoint.z - self.startPoint.z);
                            var vecRet = modelPoint.rayIntersect(model, self.startPoint, vector);
                            if (!cm7.isNull(vecRet) && vecRet != null) {
                                var retStr = '(' + vecRet.x + ',' + vecRet.y + ',' + vecRet.z + ')';
                                row.intersectPoint = retStr;
                                self.barrierBuildingMap.push(row);
                            } else {
                            }
                        }
                    }
                }
                cm7.highlightJson(self.barrierBuildingMap, 0xffff00ff);
                return self.barrierBuildingMap;
            } catch (ex) {
                alert("分析出错：\r\nexception：" + ex.message);
            } finally {
                cm7.resumeRendering();
            }
        },
        clearResult: function () {
            var self = this;
            __g.objectEditor.finishEdit();
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
            self.startPoint = null;
            self.endPoint = null;
            __g.featureManager.unhighlightAll();
            if (self.renderPolyline != null) {
                __g.objectManager.deleteObject(self.renderPolyline.guid);
                self.renderPolyline = null
            }
            __g.onobjecteditfinish = null
        },
        flyToObj: function (index, objIdName) {
            var self = this;
            for (var i = 0; i < self.barrierBuildingMap.length; i++) {
                __g.featureManager.highlightFeature(self.barrierBuildingMap[i]["featureClass"], self.barrierBuildingMap[i]["oid"], 0xffff00ff)
            }
            var row = self.barrierBuildingMap[index];
            var fc = row["featureClass"];
            var fid = row[objIdName];
            var envelope = row["envelope"];
            var angle = __g.new_EulerAngle;
            angle.set(0, -30, 0);
            __g.featureManager.highlightFeature(fc, fid, 0xff0000ff);
            __g.camera.lookAt(envelope.center, 150, angle)
        },
        flyToStartPoint: function () {
            var self = this;
            if (self.startPoint == null || self.endPoint == null) {
                return
            }
            cm7.flyToLinePoint(self.startPoint, self.endPoint)
        },
        flyToEndPoint: function () {
            var self = this;
            if (self.startPoint == null || self.endPoint == null) {
                return
            }
            cm7.flyToLinePoint(self.endPoint, self.startPoint)
        }
    };
    cm7.SightlineAnalysis = function (fcArray) {
        return new SightlineAnalysis(fcArray)
    };

    //沿路通视分析
    function RoadSightlineAnalysis(fcArray) {
        this.viewPoint = null;
        this.renderViewPoint = null;
        this.polyline = null;
        this.renderPolyline = null;
        this.renderPlArr = [];
        this.renderLinePts = [];
        this.interval = 10;
        this.offsetZ = 2;
        this.barrierBuildingMap = [];
        this.fcArray = fcArray;
    }

    RoadSightlineAnalysis.prototype = {
        constructor: RoadSightlineAnalysis,
        drawPoint: function () {
            var self = this;
            self.viewPoint = null;
            if (self.renderViewPoint != null) {
                __g.objectManager.deleteObject(self.renderViewPoint.guid);
                self.renderViewPoint = null
            }
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractEdit;
            self.viewPoint = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            self.viewPoint.setCoords(0, 0, 0, 0, 0);
            self.viewPoint.spatialCRS = _cmData.getSpatialCRS();
            var symbol = __g.new_SimplePointSymbol;
            symbol.size = 10;
            self.renderViewPoint = __g.objectManager.createRenderPoint(self.viewPoint, symbol, __rootId);
            var resultCode = __g.objectEditor.startEditRenderGeometry(self.renderViewPoint, cm7Enum.gviGeoEditType.gviGeoEditCreator);

            var EventCall = {
                onObjectEditing: function (geometry) {
                    self.viewPoint = geometry;
                },
                onObjectEditFinish: function () {
                    __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
                }
            }
            __g.callback = EventCall;
        },
        drawLine: function () {
            var self = this;
            self.clear();
            self.polyline = null;
            if (self.renderPolyline != null) {
                __g.objectManager.deleteObject(self.renderPolyline.guid);
                self.renderPolyline = null
            }
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractEdit;
            self.polyline = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolyline, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            self.renderPolyline = __g.objectManager.createRenderPolyline(self.polyline, null, __rootId);
            var resultCode = __g.objectEditor.startEditRenderGeometry(self.renderPolyline, cm7Enum.gviGeoEditType.gviGeoEditCreator);

            var EventCall = {
                onObjectEditing: function (geometry) {
                    self.polyline = geometry;
                },
                onObjectEditFinish: function () {
                    // __g.onobjecteditfinish = null;
                    __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
                }
            }
            __g.callback = EventCall;

        },
        analysis: function () {
            var self = this;
            try {
                if (self.viewPoint === null) {
                    alert('请选择观测点！');
                    return [];
                }
                if (self.polyline === null) {
                    alert('请沿路绘线！');
                    return [];
                }

                cm7.pauseRendering();
                var geoFactory = __g.geometryFactory;
                var gc = __g.geometryConvertor;
                var crs = _cmData.getSpatialCRS();
                var linePts = [];
                var symbol = __g.new_SimplePointSymbol;
                symbol.size = 6;
                var curveSymbol = __g.new_CurveSymbol;
                curveSymbol.color = 0xffff00ff;
                var polygon = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolygon, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                var ring = polygon.exteriorRing;
                var ringPt = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                ringPt.spatialCRS = crs;
                ringPt.setCoords(self.viewPoint.x, self.viewPoint.y, 100, 0, 0);
                ring.appendPoint(ringPt);
                for (var i = 0; i < self.polyline.pointCount; i++) {
                    var pt1 = self.polyline.getPoint(i);
                    linePts.push(pt1);
                    ringPt.setCoords(pt1.x, pt1.y, 100, 0, 0);
                    ring.appendPoint(ringPt);
                    if (i === self.polyline.pointCount - 1) {
                        continue;
                    }

                    var pt2 = self.polyline.getPoint(i + 1);
                    var dis = ptToPtDistance(pt1, pt2);
                    if (dis > self.interval) {
                        var ln = self.interval;
                        while (ln < dis) {
                            var delta = ln / (dis - ln);
                            if (delta != -1) {
                                var ptx = (pt1.x + delta * pt2.x) / (1 + delta);
                                var pty = (pt1.y + delta * pt2.y) / (1 + delta);
                                var ptz = (pt1.z + delta * pt2.z) / (1 + delta);
                                var newPt = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                                newPt.spatialCRS = crs;
                                newPt.setCoords(ptx, pty, ptz, 0, 0);
                                linePts.push(newPt);
                                ln += self.interval;
                                self.renderLinePts.push(__g.objectManager.createRenderPoint(newPt, symbol, __rootId));
                            }
                        }
                    }
                }

                ringPt.setCoords(self.viewPoint.x, self.viewPoint.y, 100, 0, 0);
                ring.appendPoint(ringPt);

                var surfaceSymbol = __g.new_SurfaceSymbol;
                surfaceSymbol.color = 0x55ffff80;
                // var renderPolygon = __g.objectManager.createRenderPolygon(polygon, surfaceSymbol, __rootId);
                var lineArr = [];
                var lineVector = [];
                for (var q = 0; q < linePts.length; q++) {
                    var pt = linePts[q];
                    var l = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryLine, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                    l.startPoint = self.viewPoint;
                    l.endPoint = linePts[q];
                    lineArr.push(l);
                    lineVector.push(cm7.newVector3(pt.x - self.viewPoint.x, pt.y - self.viewPoint.y, pt.z - self.viewPoint.z));
                    var pl = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolyline, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                    pl.appendPoint(self.viewPoint);
                    pl.appendPoint(linePts[q]);
                    self.renderPlArr.push(__g.objectManager.createRenderPolyline(pl, null, __rootId));
                }

                var filter = __g.new_SpatialFilter;
                filter.geometry = polygon;
                filter.spatialRel = cm7Enum.gviSpatialRel.gviSpatialRelEnvelope;
                filter.geometryField = "Geometry";

                for (var j = 0; j < self.fcArray.length; j++) {
                    var fc = self.fcArray[j];
                    var rows = fc.query(filter);

                    for (var t = 0; t < rows.length; t++) {
                        var row = rows[t];
                        var modelPoint = row.Geometry;
                        if (modelPoint.modelName) {
                            var model = fc.obj.featureDataSet.getModel(modelPoint.modelName);
                            var flag = false; //是否遮挡
                            for (var k = 0; k < lineVector.length; k++) {
                                var vecRet = modelPoint.rayIntersect(model, self.viewPoint, lineVector[k]);
                                if (!cm7.isNull(vecRet) && vecRet != null) {
                                    flag = true;
                                    self.renderPlArr[k].symbol = curveSymbol;
                                }
                            }
                            if (flag) {
                                self.barrierBuildingMap.push(row);
                                cm7.highlightJson(row);
                            }
                        }
                    }
                }
                return self.barrierBuildingMap;
            } catch (e) {
                alert('分析出错：' + e.message);
            } finally {
                cm7.resumeRendering();
            }
        },
        clear: function () {
            var self = this;
            __g.objectEditor.finishEdit();
            self.barrierBuildingMap = [];
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
            __g.featureManager.unhighlightAll();
            self.polyline = null;
            if (self.renderPolyline != null) {
                __g.objectManager.deleteObject(self.renderPolyline.guid);
                self.renderPolyline = null
            }
            self.viewPoint = null;
            if (self.renderViewPoint != null) {
                __g.objectManager.deleteObject(self.renderViewPoint.guid);
                self.renderViewPoint = null
            }

            var renderPlTmp = null;
            while (renderPlTmp = self.renderPlArr.pop()) {
                __g.objectManager.deleteObject(renderPlTmp.guid);
                renderPlTmp = null;
            }

            var renderPtTmp = null;
            while (renderPtTmp = self.renderLinePts.pop()) {
                __g.objectManager.deleteObject(renderPtTmp.guid);
                renderPtTmp = null;
            }
            __g.onobjecteditfinish = null

        },
    };
    cm7.RoadSightlineAnalysis = function (fcArray) {
        return new RoadSightlineAnalysis(fcArray);
    };


    function WktConvert() {

    }

    WktConvert.prototype = {
        constructor: WktConvert,
        getType: function (wkt) {

        },
        getPolygonPtList: function (wkt) {
            var ret = [];
            var strPts = wkt.replace('polygon ((', '').replace('))', '');
            var pts = strPts.split(',');
            for (var i = 0; i < pts.length; i++) {
                var pt = pts[i].split(' ');
                var pos = {
                    x: pt[0],
                    y: pt[1]
                };
                ret.push(pos);
            }
            return ret;
        }
    };
    var _wktConvert = null;
    cm7.getWktConvert = function () {
        if (!_wktConvert) {
            _wktConvert = new WktConvert();
        }
        return _wktConvert
    };


    function ptToPtDistance(pt1, pt2) {
        pt1.z = pt1.z ? pt1.z : 0;
        pt2.z = pt2.z ? pt2.z : 0;
        return Math.sqrt((pt1.x - pt2.x) * (pt1.x - pt2.x) + (pt1.y - pt2.y) * (pt1.y - pt2.y) + (pt1.z - pt2.z) * (pt1.z - pt2.z));
    }

    function ModelDistance() {
        this.firstFeatrue = null;
        this.secondFeature = null;
        this.polyline = null;
        this.renPolyline = null;
        this.offsetZ = 10;
    }

    ModelDistance.prototype = {
        constructor: ModelDistance,
        selectModel: function () {
            var self = this,
                pCount = 0;
            __g.highlightHelper.visibleMask = cm7Enum.gviViewportMask.gviViewAllNormalView;
            __g.highlightHelper.setRegion(null);
            __g.visualAnalysis.stopAnalyse();
            __g.featureManager.unhighlightAll();
            var pmi = new PickModelHelper();
            pmi.pickModel(function (row, pickResult, intersectPoint, mask, eventSender) {
                cm7.highlightJson(row);
                if (pCount === 0) {
                    self.firstFeatrue = row;
                } else if (pCount === 1) {
                    self.secondFeature = row;
                    pmi.exitPick();
                }
                pCount++;
            })
        },
        ananlysis: function () {
            var self = this;
            if (!self.firstFeatrue || !self.secondFeature) {
                alert('请选择两栋建筑物！');
                return null;
            }

            if (self.renPolyline) {
                __g.objectManager.deleteObject(self.renPolyline.guid);
            }
            self.renPolyline = null;

            var gc = new GeometryConvert();
            var prjGeo1 = gc.projectModelPointToPolygon(self.firstFeatrue.fcObj, self.firstFeatrue.Geometry, 0.1);
            var prjGeo2 = gc.projectModelPointToPolygon(self.secondFeature.fcObj, self.secondFeature.Geometry, 0.1);

            var ptColl1 = [],
                ptColl2 = [],
                minPt1 = null,
                minPt2 = null,
                minDis = 999999999999;
            for (var i = 0; i < prjGeo1.geometryCount; i++) {
                var wkt1 = prjGeo1.getGeometry(i).asWKT();
                ptColl1 = ptColl1.concat(cm7.getWktConvert().getPolygonPtList(wkt1));
            }

            for (var j = 0; j < prjGeo2.geometryCount; j++) {
                var wkt2 = prjGeo2.getGeometry(j).asWKT();
                ptColl2 = ptColl2.concat(cm7.getWktConvert().getPolygonPtList(wkt2));
            }

            for (var i1 in ptColl1) {
                var pt1 = ptColl1[i1];
                for (var i2 in ptColl2) {
                    var pt2 = ptColl2[i2];
                    var dis = ptToPtDistance(pt1, pt2);
                    if (dis < minDis) {
                        minPt1 = pt1;
                        minPt2 = pt2;
                        minDis = dis;
                    }
                }
            }

            minPt1.z = self.offsetZ;
            minPt2.z = self.offsetZ;

            //绘线
            var fdePt1 = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            fdePt1.setCoords(minPt1.x, minPt1.y, minPt1.z, 0, 0);
            var fdePt2 = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            fdePt2.setCoords(minPt2.x, minPt2.y, minPt2.z, 0, 0);

            self.polyline = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolyline, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            self.polyline.appendPoint(fdePt1);
            self.polyline.appendPoint(fdePt2);

            var curveSymbol = __g.new_CurveSymbol;
            curveSymbol.width = 2;
            self.renPolyline = __g.objectManager.createRenderPolyline(self.polyline, curveSymbol, __rootId);

            return {
                minPt1: minPt1,
                minPt2: minPt2,
                minDis: minDis
            }

        },
        clear: function () {
            cm7.unhighlightAll();
            this.firstFeatrue = null;
            this.secondFeature = null;
            this.polyline = null;
            if (this.renPolyline) {
                __g.objectManager.deleteObject(this.renPolyline.guid);
            }
            this.renPolyline = null;
        }
    };
    cm7.ModelDistance = function () {
        return new ModelDistance();
    };

    function ptToLineDistance(pt, ps, pe) {
        var pqx = ps.x - pe.x,
            pqy = ps.y - pe.y,
            pqz = ps.z - pe.z,
            dx = pt.x - ps.x,
            dy = pt.y - ps.y,
            dz = pt.z - ps.z,
            d = pqx * pqx + pqy * pqy + pqz * pqz,
            t = pqx * dx + pqy * dy + pqz * dz;
        if (d > 0) {
            t = t / d
        }
        if (t < 0) {
            t = 0
        } else if (t > 1) {
            t = 1
        }
        dx = ps.x + t * pqx - pt.x;
        dy = ps.y + t * pqy - pt.y;
        dz = ps.z + t * pqz - pt.z;
        return dx * dx + dy * dy + dz * dz
    }

    // 区域控高分析
    function BuildingHeightAnalysis(fcArray) {
        this.editGeoVH = null;
        this.renderPolygons = [];
        this.violationHeight = 10;
        this.fcArray = fcArray;
        this.violationBuildingMap = [];
        this.drawHelper = new DrawHelper();
    }

    BuildingHeightAnalysis.prototype = {
        drawPolygon: function () {
            this.clear();
            this.drawHelper.drawPolygon()
        },
        clear: function () {
            __g.featureManager.unhighlightAll();
            this.drawHelper.clear();

            for (var item in this.renderPolygons) {
                __g.objectManager.deleteObject(this.renderPolygons[item].guid);
            }

            this.renderPolygons = [];
        },
        clearPolygon: function () {
            this.drawHelper.clear()
        },
        analysisViolationBuilding: function () {
            var self = this;
            try {
                // var geometry = self.drawHelper.geometry;
                var geometry = self.drawHelper.renderGeometry.getFdeGeometry();
                self.drawHelper.clear();

                if (geometry === null || geometry.isEmpty === true || geometry.isClosed === false) {
                    alert("请绘制一个完整的范围。");
                    return
                }
                cm7.pauseRendering();

                var surfaceSymbol = __g.new_SurfaceSymbol;
                surfaceSymbol.color = 0x99e9f596;
                var polygonTop = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolygon, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                var ringTop = polygonTop.exteriorRing;
                var polygonBottom = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolygon, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                var ringBottom = polygonBottom.exteriorRing;
                var crs = _cmData.getSpatialCRS();

                var ring = geometry.exteriorRing;
                for (var k = 0; k < ring.pointCount; k++) {
                    var pt = ring.getPoint(k);
                    var pointTop = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                    pointTop.spatialCRS = crs;
                    pointTop.setCoords(pt.x, pt.y, self.violationHeight, 0, 0);
                    ringTop.appendPoint(pointTop);

                    var pointBottom = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                    pointBottom.spatialCRS = crs;
                    pointBottom.setCoords(pt.x, pt.y, 0, 0, 0);
                    ringBottom.appendPoint(pointBottom);
                }
                // 加入顶部多边形
                this.renderPolygons.push(__g.objectManager.createRenderPolygon(polygonTop, surfaceSymbol, __rootId));
                this.renderPolygons.push(__g.objectManager.createRenderPolygon(polygonBottom, surfaceSymbol, __rootId));
                // 加入四周多边形

                for (var k = 0; k < ringBottom.pointCount - 1; k++) {
                    var pointBottom = ringBottom.getPoint(k);
                    var point2Bottom = ringBottom.getPoint(k + 1);
                    var point = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                    point.spatialCRS = crs;
                    point.setCoords(pointBottom.x, pointBottom.y, pointBottom.z, 0, 0);

                    var point2 = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                    point2.spatialCRS = crs;
                    point2.setCoords(point2Bottom.x, point2Bottom.y, point2Bottom.z, 0, 0);
                    var point3 = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                    point3.spatialCRS = crs;
                    point3.setCoords(point2Bottom.x, point2Bottom.y, self.violationHeight, 0, 0);
                    var point4 = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                    point4.spatialCRS = crs;
                    point4.setCoords(pointBottom.x, pointBottom.y, self.violationHeight, 0, 0);

                    var polygon = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolygon, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                    var ring = polygon.exteriorRing;
                    ring.appendPoint(point);
                    ring.appendPoint(point2);
                    ring.appendPoint(point3);
                    ring.appendPoint(point4);

                    this.renderPolygons.push(__g.objectManager.createRenderPolygon(polygon, surfaceSymbol, __rootId));
                }
                self.violationBuildingMap = [];
                var filter = __g.new_SpatialFilter;
                filter.geometry = geometry;
                filter.spatialRel = cm7Enum.gviSpatialRel.gviSpatialRelIntersects;
                filter.geometryField = "Geometry";
                for (var i = 0; i < self.fcArray.length; i++) {
                    var rows = self.fcArray[i].query(filter);
                    for (var j = 0; j < rows.length; j++) {
                        var row = rows[j];
                        if (row.Geometry != null) {
                            // cm7.highlightJson(row, 0xffe9f596);;
                            var buildingHeight = row.Geometry.envelope.height;
                            if (buildingHeight > self.violationHeight) {
                                self.violationBuildingMap.push(row);
                                cm7.highlightJson(row);
                            }
                        }
                    }
                }
                return self.violationBuildingMap;
            } catch (ex) {
                alert('分析出错：' + ex.message);
            } finally {
                cm7.resumeRendering();
            }
        }
    };
    cm7.BuildingHeightAnalysis = function (fcArray) {
        return new BuildingHeightAnalysis(fcArray)
    };


    function ExportImage() {
        this.polyline = null;
        this.renderPolyLine = null
    }

    ExportImage.prototype = {
        constructor: ExportImage,
        drawOrthoImageLine: function () {
            var self = this;
            self.clear();
            self.polyline = null;
            if (self.renderPolyline != null) {
                __g.objectManager.deleteObject(self.renderPolyline.guid);
                self.renderPolyline = null
            }
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractEdit;
            self.polyline = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolyline, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            self.renderPolyline = __g.objectManager.createRenderPolyline(self.polyline, null, __rootId);
            var resultCode = __g.objectEditor.startEditRenderGeometry(self.renderPolyline, cm7Enum.gviGeoEditType.gviGeoEditCreator);

            var EventCall = {
                onObjectEditing: function (geometry) {
                    self.polyline = geometry;
                },
                onObjectEditFinish: function () {
                    __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
                }
            };
            __g.callback = EventCall;
        },
        exportOrthoImage: function (savePath, size, isHighQuality) {
            var self = this;
            if (self.polyline == null || self.polyline.pointCount < 2) {
                alert("请绘制一条直线！");
                return false;
            }
            var angle = __g.camera.getAimingAngles2(self.polyline.getPoint(0), self.polyline.getPoint(1));
            var cameraAngle = __g.new_EulerAngle;
            cameraAngle.heading = angle.heading - 90;
            cameraAngle.tilt = 0;
            cameraAngle.roll = 0;
            var centerPt = self.polyline.midpoint;
            centerPt.spatialCRS = _cmData.getSpatialCRS();
            var newEnv = __g.new_Envelope;
            newEnv.minX = -self.polyline.length / 2;
            newEnv.maxX = self.polyline.length / 2;
            newEnv.minY = -5;
            newEnv.maxY = 150;
            newEnv.minZ = -500;
            newEnv.maxZ = 0;
            var res = __g.exportManager.exportOrthoImage(savePath, size, centerPt, cameraAngle, newEnv, isHighQuality, 0xff00ffff);
            if (res) {
                alert("图片已经保存在：" + savePath)
            }
            if (self.renderPolyLine != null) {
                __g.objectManager.deleteObject(self.renderPolyLine.guid);
                self.renderPolyLine = null
            }
            return res;
        },
        exportPanorama: function (savePath, size) {
            var cameraInfo = __g.camera.getCamera();
            var center = __g.geometryFactory.createPoint(cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            center.spatialCRS = _cmData.getSpatialCRS();
            center.position = cameraInfo.position;
            var angle = cameraInfo.angle;
            var res = __g.exportManager.exportPanorama(savePath, size, center, angle);
            if (res) {
                alert("图片已经保存在：" + savePath)
            }
            return res;
        },
        captureScreen: function (path, width, height, isHigquality) {
            var ret = __g.exportManager.exportImage(path, width, height, isHigquality);
            return ret;
        },
        clear: function () {
            var self = this;
            __g.objectEditor.finishEdit();
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
            __g.featureManager.unhighlightAll();
            self.polyline = null;
            if (self.renderPolyline != null) {
                __g.objectManager.deleteObject(self.renderPolyline.guid);
                self.renderPolyline = null
            }
        },
    };
    cm7.ExportImage = function () {
        return new ExportImage()
    };


    // 视域分析
    function ViewshedAnalysis(fcArray) {
        this.startPoint = {};
        this.endPoint = {};
        this.geo = null;
        this.renderPolyline = null;
        this.drawFirstPointFunc = null;
        this.drawLastPointFunc = null;
        this.angle = 60;
        this.offsetH = 1.7;
        this.fde_point1 = null;
        this.fde_point2 = null;
        this.fcArray = fcArray;
        this.viewshed = null;
    }

    ViewshedAnalysis.prototype = {
        constructor: ViewshedAnalysis,
        drawLine1: function () {
            var self = this;
            __g.highlightHelper.visibleMask = cm7Enum.gviViewportMask.gviViewAllNormalView;
            __g.highlightHelper.setRegion(null);
            __g.visualAnalysis.stopAnalyse();
            __g.featureManager.unhighlightAll();
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractSelect;
            __g.mouseSelectObjectMask = cm7Enum.gviMouseSelectObjectMask.gviSelectAll;
            __g.mouseSelectMode = cm7Enum.gviMouseSelectMode.gviMouseSelectClick;
            __g.onobjectediting = function (geometry) {
                self.geo = geometry;
                if (geometry.pointCount == 1) {
                    if (self.drawFirstPointFunc != null) {
                        self.drawFirstPointFunc(self.geo.getPoint(0))
                    }
                }
                if (geometry.pointCount >= 2) {
                    __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
                    self.startPoint = self.geo.getPoint(0);
                    self.endPoint = self.geo.getPoint(1);
                    self.analysis();
                    if (self.drawLastPointFunc != null) {
                        self.drawLastPointFunc(self.geo.getPoint(1))
                    }
                }
            };
            __g.onobjecteditfinish = function () {
                __g.onobjecteditfinish = null
            };
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractEdit;
            self.geo = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolyline, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            self.renderPolyline = __g.objectManager.createRenderPolyline(self.geo, null, __rootId);
            var resultCode = __g.objectEditor.startEditRenderGeometry(self.renderPolyline, cm7Enum.gviGeoEditType.gviGeoEditCreator)
        },
        draw: function () {
            var self = this;
            __g.highlightHelper.visibleMask = cm7Enum.gviViewportMask.gviViewAllNormalView;
            __g.highlightHelper.setRegion(null);
            __g.visualAnalysis.stopAnalyse();
            __g.featureManager.unhighlightAll();
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractSelect;
            __g.mouseSelectObjectMask = cm7Enum.gviMouseSelectObjectMask.gviSelectAll;
            __g.mouseSelectMode = cm7Enum.gviMouseSelectMode.gviMouseSelectClick;
            var geoFactory = __g.geometryFactory;
            var mouseClicks = 0;

            self.startPoint = {};
            self.endPoint = {};

            var EventCall = {
                onMouseClickSelect: function (pickResult, intersectPoint, mask, eventSender) {
                    if (intersectPoint == null) {
                        return
                    }
                    if (eventSender === cm7Enum.gviMouseSelectMode.gviMouseSelectClick) {
                        mouseClicks++;
                        if (mouseClicks === 1) {
                            self.startPoint.x = intersectPoint.x;
                            self.startPoint.y = intersectPoint.y;
                            self.startPoint.z = parseFloat(intersectPoint.z) + parseFloat(self.offsetH);
                            // __g.mouseSelectMode = cm7Enum.gviMouseSelectMode.gviMouseSelectClick | cm7Enum.gviMouseSelectMode.gviMouseSelectMove;
                            if (self.drawFirstPointFunc != null) {
                                self.drawFirstPointFunc(self.startPoint)
                            }
                        } else {
                            __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
                            __g.mouseSelectObjectMask = cm7Enum.gviMouseSelectObjectMask.gviSelectNone;
                            __g.mouseSelectMode = cm7Enum.gviMouseSelectMode.gviMouseSelectClick;
                            mouseClicks = 0;
                            try {
                                self.endPoint.x = intersectPoint.x;
                                self.endPoint.y = intersectPoint.y;
                                self.endPoint.z = parseFloat(intersectPoint.z) + parseFloat(self.offsetH);
                                if (self.drawLastPointFunc != null) {
                                    self.drawLastPointFunc(self.endPoint)
                                }
                                // self.fde_point1 = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                                // self.fde_point1.setCoords(self.startPoint.x, self.startPoint.y, self.startPoint.z, 0, 0);
                                // self.fde_point2 = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                                // self.fde_point2.setCoords(self.endPoint.x, self.endPoint.y, self.endPoint.z, 0, 0)
                            } catch (ex) {
                                alert("发生错误：" + ex)
                            }
                        }
                    }
                    // else if (eventSender === cm7Enum.gviMouseSelectMode.gviMouseSelectMove) {
                    //     self.endPoint.x = intersectPoint.x;
                    //     self.endPoint.y = intersectPoint.y;
                    //     self.endPoint.z = intersectPoint.z + self.offsetH;
                    //     if (self.drawLastPointFunc != null) {
                    //         self.drawLastPointFunc(self.endPoint)
                    //     }
                    //     self.fde_point1 = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                    //     self.fde_point1.setCoords(self.startPoint.x, self.startPoint.y,parseFloat(self.startPoint.z), 0, 0);
                    //     self.fde_point2 = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                    //     self.fde_point2.setCoords(self.endPoint.x, self.endPoint.y, self.endPoint.z, 0, 0);
                    //     __g.highlightHelper.setSectorRegion(self.fde_point1, self.fde_point2, self.angle)
                    // }
                }
            };
            __g.callback = EventCall;
        },
        analysis: function (fde_point1, fde_point2) {
            var self = this;
            try {
                // cm7.pauseRendering();
                // var filter = __g.new_SpatialFilter;
                // filter.geometry = __g.highlightHelper.getRegion();
                // filter.spatialRel = cm7Enum.gviSpatialRel.gviSpatialRelEnvelope;
                // filter.geometryField = "Geometry";
                // for (var i = 0; i < self.fcArray.length; i++) {
                //     var fc = self.fcArray[i],
                //         fl = fc.layer;
                //     var rows = fc.query(filter);
                //     console.log(fc.name);
                //     console.log(rows.length);
                //     rows.forEach(function (row) {
                //         var modelPoint = row.Geometry;
                //         __g.visualAnalysis.addOccluder(fl, modelPoint)
                //     })
                // }
                // __g.visualAnalysis.startViewshedAnalyse(fde_point1, fde_point2, self.angle);
                var pos = __g.geometryFactory.createPoint(1);
                pos.x = this.startPoint.x;
                pos.y = this.startPoint.y;
                pos.z = this.startPoint.z;
                if (this.viewshed == null) {
                    this.viewshed = __g.objectManager.createViewshed(pos, __rootId);
                } else {
                    this.viewshed.visibleMask = cm7Enum.gviViewportMask.gviViewAllNormalView;
                    this.viewshed.position = pos;
                }

                var eulerAngle = __g.new_EulerAngle;
                var xx = parseFloat(this.endPoint.x) - parseFloat(this.startPoint.x);
                var yy = parseFloat(this.endPoint.y) - parseFloat(this.startPoint.y);
                var zz = parseFloat(this.endPoint.z) - parseFloat(this.startPoint.z);
                var heading = Math.atan(xx / yy) * (180 / 3.1416);
                var pitch = Math.atan(zz / Math.sqrt(xx * xx + yy * yy)) * (180 / 3.1416);
                if (yy < 0) {
                    heading += 180;
                }
                eulerAngle.set(heading, pitch, 0);
                this.viewshed.angle = eulerAngle;
                this.viewshed.displayMode = cm7Enum.gviTVDisplayMode.gviTVShowLinesAndPicture;
            } catch (ex) {
                alert('分析出错：' + ex.message);
            }
            // finally {
            //     cm7.resumeRendering();
            // }
        },
        clearResult: function () {
            __g.visualAnalysis.stopAnalyse();
            __g.highlightHelper.setRegion(null);
            __g.featureManager.unhighlightAll();
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
            __g.mouseSelectObjectMask = cm7Enum.gviMouseSelectObjectMask.gviSelectNone;
            __g.mouseSelectMode = cm7Enum.gviMouseSelectMode.gviMouseSelectClick;
            __g.onmouseclickselect = null;
            this.startPoint = {};
            this.endPoint = {};
            if (this.viewshed) {
                this.viewshed.visibleMask = cm7Enum.gviViewportMask.gviViewNone;
            }
        }
    };
    cm7.ViewshedAnalysis = function (fcArray) {
        return new ViewshedAnalysis(fcArray)
    };


    function getGMTStr(date) {
        var s = "";
        var hours = date.getHours() - 8 >= 0 ? date.getHours() - 8 : date.getHours() - 8 + 24;
        s = date.getFullYear() + "/" + date.getMonth() + "/" + date.getDate() + " " + hours + ":" + date.getMinutes() + ":" + date.getSeconds();
        return s
    }

    function calPointsEnvelopePolygon(ptArr) {
        var crs = _cmData.getSpatialCRS();
        var minX = minY = minZ = 999999999999,
            maxX = maxY = maxZ = -999999999999;

        for (var i = 0; i < ptArr.length; i++) {
            var pt = ptArr[i];
            minX = pt.x < minX ? pt.x : minX;
            maxX = pt.x > maxX ? pt.x : maxX;

            minY = pt.y < minY ? pt.y : minY;
            maxY = pt.y > maxY ? pt.y : maxY;

            minZ = pt.z < minZ ? pt.z : minZ;
            maxZ = pt.z > maxZ ? pt.z : maxZ;
        }

        var polygon = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolygon, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
        var ring = polygon.exteriorRing;

        var envPt1 = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
        envPt1.spatialCRS = crs;
        envPt1.setCoords(minX, minY, maxZ, 0, 0);
        ring.appendPoint(envPt1);

        var envPt2 = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
        envPt2.spatialCRS = crs;
        envPt2.setCoords(maxX, minY, maxZ, 0, 0);
        ring.appendPoint(envPt2);

        var envPt3 = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
        envPt3.spatialCRS = crs;
        envPt3.setCoords(maxX, maxY, maxZ, 0, 0);
        ring.appendPoint(envPt3);

        var envPt4 = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
        envPt4.spatialCRS = crs;
        envPt4.setCoords(minX, maxY, maxZ, 0, 0);
        ring.appendPoint(envPt4);
        return polygon;
    }


    function ShadowAnalysis(fcArray) {
        this.fcArray = fcArray;
        this.startPoint = {};
        this.endPoint = {};
        this.interval = null;
        this.autoAnalysisDateChangeFunc = null;
        this.drawFirstPointFunc = null;
        this.drawLastPointFunc = null;
        this.isAnalysis = false;
        var ang = __g.new_EulerAngle;
        ang.heading = -15;
        ang.tilt = -20;
        __g.sunConfig.sunCalculateMode = cm7Enum.gviSunCalculateMode.gviSunModeAccordingToGMT;
        __g.sunConfig.setSunEuler(ang);
        __g.sunConfig.shadowColor = 2566914048
    }

    ShadowAnalysis.prototype = {
        constructor: ShadowAnalysis,
        getStringGMT: function (date) {
            var s = "";
            var hours = date.getHours() - 8 >= 0 ? date.getHours() - 8 : date.getHours() - 8 + 24;
            s = date.getFullYear() + "/" + date.getMonth() + "/" + date.getDate() + " " + hours + ":" + date.getMinutes() + ":" + date.getSeconds();
            return s
        },
        GMTToDate: function (GMT) {

        },
        showShadow: function () {
            __g.sunConfig.enableShadow(0, true);
        },
        unshowShadow: function () {
            __g.sunConfig.enableShadow(0, false);
        },
        setDate: function (date) {
            var self = this;
            var d = self.getStringGMT(date);
            __g.sunConfig.setGMT(d);
        },
        startShadowAnalyse: function (date) {
            var self = this;
            try {
                self.stopAnalyse();
                self.setDate(date);
                __g.sunConfig.enableShadow(0, true);
                self.isAnalysis = true;
                return true;
            } catch (ex) {
                alert(ex);
            }
        },
        stopAnalyse: function () {
            __g.sunConfig.enableShadow(0, false);
            this.isAnalysis = false;
        },
        autoShadowAnalyse: function (initDate) {
            var self = this;
            var bl = self.startShadowAnalyse(initDate);
            if (!bl) {
                return false;
            }
            self.interval = setInterval(function () {
                var h = initDate.getHours();
                if (h === 23) {
                    initDate.setHours(0);
                } else {
                    h++;
                    initDate.setHours(h);
                }
                if (h < 20 && h > 5) {
                    self.setDate(initDate);
                }
                if (self.autoAnalysisDateChangeFunc != null) {
                    self.autoAnalysisDateChangeFunc(initDate)
                }
            }, 1000);
            return true;
        },
        pauseAutoAnalysis: function () {
            var self = this;
            if (self.interval != null) {
                clearInterval(self.interval)
            }
        },
        draw: function () {
            var self = this;
            __g.highlightHelper.visibleMask = cm7Enum.gviViewportMask.gviViewAllNormalView;
            __g.highlightHelper.setRegion(null);
            self.stopAnalyse();
            __g.featureManager.unhighlightAll();
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractSelect;
            __g.mouseSelectObjectMask = cm7Enum.gviMouseSelectObjectMask.gviSelectAll;
            __g.mouseSelectMode = cm7Enum.gviMouseSelectMode.gviMouseSelectClick;
            var geoFactory = __g.geometryFactory;
            var mouseClicks = 0;
            var fde_point1 = null;
            var fde_point2 = null;

            var EventCall = {
                onMouseClickSelect: function (pickResult, intersectPoint, mask, eventSender) {
                    if (intersectPoint == null) {
                        return
                    }
                    if (eventSender === cm7Enum.gviMouseSelectMode.gviMouseSelectClick) {
                        mouseClicks++;
                        if (mouseClicks === 1) {
                            self.startPoint.x = intersectPoint.x;
                            self.startPoint.y = intersectPoint.y;
                            self.startPoint.z = intersectPoint.z + self.offsetH;
                            __g.mouseSelectMode = cm7Enum.gviMouseSelectMode.gviMouseSelectClick | cm7Enum.gviMouseSelectMode.gviMouseSelectMove;
                            if (self.drawFirstPointFunc != null) {
                                self.drawFirstPointFunc(self.startPoint)
                            }
                        } else {
                            __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
                            __g.mouseSelectObjectMask = cm7Enum.gviMouseSelectObjectMask.gviSelectNone;
                            __g.mouseSelectMode = cm7Enum.gviMouseSelectMode.gviMouseSelectClick;
                            mouseClicks = 0;
                            try {
                                self.endPoint.x = intersectPoint.x;
                                self.endPoint.y = intersectPoint.y;
                                self.endPoint.z = intersectPoint.z + self.offsetH;
                                if (self.drawLastPointFunc != null) {
                                    self.drawLastPointFunc(self.endPoint)
                                }
                                fde_point1 = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                                fde_point1.setCoords(self.startPoint.x, self.startPoint.y, self.startPoint.z, 0, 0);
                                fde_point2 = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                                fde_point2.setCoords(self.endPoint.x, self.endPoint.y, self.endPoint.z, 0, 0)
                            } catch (ex) {
                                alert("发生错误：" + ex)
                            }
                        }
                    } else if (eventSender === cm7Enum.gviMouseSelectMode.gviMouseSelectMove) {
                        self.endPoint.x = intersectPoint.x;
                        self.endPoint.y = intersectPoint.y;
                        self.endPoint.z = intersectPoint.z + self.offsetH;
                        if (self.drawLastPointFunc != null) {
                            self.drawLastPointFunc(self.endPoint)
                        }
                        fde_point1 = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                        fde_point1.setCoords(self.startPoint.x, self.startPoint.y, self.startPoint.z, 0, 0);
                        fde_point2 = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                        fde_point2.setCoords(self.endPoint.x, self.endPoint.y, self.endPoint.z, 0, 0);
                        __g.highlightHelper.setSectorRegion(fde_point1, fde_point2, 360)
                    }
                }
            };
            __g.callback = EventCall;
        },
        clear: function () {

            if (this.interval) {
                clearInterval(this.interval);
            }
            this.stopAnalyse();
            // __g.onmouseclickselect = null;
            this.startPoint = {};
            this.endPoint = {};
            this.interval = null;
            __g.highlightHelper.visibleMask = cm7Enum.gviViewportMask.gviViewAllNormalView;
            __g.highlightHelper.setRegion(null);
            __g.featureManager.unhighlightAll();
        },
        dispose: function () {
            if (this.interval) {
                clearInterval(this.interval);
            }
            this.stopAnalyse();
            __g.onmouseclickselect = null;
            this.startPoint = {};
            this.endPoint = {};
            this.interval = null;

            this.fcArray = null;
            this.autoAnalysisDateChangeFunc = null;
            this.drawFirstPointFunc = null;
            this.drawLastPointFunc = null;
            __g.highlightHelper.visibleMask = cm7Enum.gviViewportMask.gviViewAllNormalView;
            __g.highlightHelper.setRegion(null);
            __g.featureManager.unhighlightAll();
        }
    };
    cm7.ShadowAnalysis = function (fcArr) {
        return new ShadowAnalysis(fcArr)
    };

// 单点日照时长分析
    function PointShadowAnalysis(fcArray) {
        this.startTime = {};
        this.endTime = {};
        this.sampleInterval = 5; //
        this.interval = 10; //单位分钟
        this.targetPoint = null;
        this.renderTargetPoint = null;
        this.sunRiseSunSet = null;
        this.renderPlArr = [];
        this.maxRadius = 500;
        this.fcArray = fcArray;
    }

    PointShadowAnalysis.prototype = {
        constructor: PointShadowAnalysis,
        drawPoint: function () {
            var self = this;
            self.clear();
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractEdit;
            self.targetPoint = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            self.targetPoint.setCoords(0, 0, 0, 0, 0);
            self.targetPoint.spatialCRS = _cmData.getSpatialCRS();
            var symbol = __g.new_SimplePointSymbol;
            symbol.size = 10;
            self.renderTargetPoint = __g.objectManager.createRenderPoint(self.targetPoint, symbol, __rootId);
            var resultCode = __g.objectEditor.startEditRenderGeometry(self.renderTargetPoint, cm7Enum.gviGeoEditType.gviGeoEditCreator);
            var EventCall = {
                onObjectEditing: function (geometry) {
                    self.targetPoint = geometry;
                },
                onObjectEditFinish: function () {
                    __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
                }
            }
            __g.callback = EventCall;
        },
        calSunRiseSunSet: function (b, l, s) {
            this.sunRiseSunSet = computeSunRiseSunSet(b, l, s);
            return this.sunRiseSunSet;
        },
        calSunLocation: function (tarPt, interval, sunRise, sunSet) {
            var self = this;
            var sunRR = self.calSunRiseSunSet();
            var timeSpan = sunSet.getTime() - sunRise.getTime();
            interval = interval * 60;
        },
        analysis: function () {
            try {
                cm7.pauseRendering();
                var self = this;
                var plArr = [];
                var ca = __g.camera.getCamera();
                var v0 = cm7.newVector3(ca.position.x, ca.position.y, ca.position.z);
                var v1 = cm7.newVector3(self.targetPoint.x, self.targetPoint.y, self.targetPoint.z);
                var abAng = __g.camera.getAimingAngles(v0, v1);
                var ptTmp = __g.camera.getAimingPoint2(self.targetPoint, abAng, -0.5);
                // ptTmp.z += 10;
                var interval = self.interval * 60 * 1000;
                // var pt84 = ptTmp.clone();
                // pt84.spatialCRS = _cmData.getSpatialCRS();
                // var crs84 = __g.crsFactory.createWGS84();
                // pt84.project(crs84);
                // pt84.spatialCRS = crs84;
                var st = self.startTime.getTime();
                var et = self.endTime.getTime();
                var sunPtArr = [];
                __g.sunConfig.sunCalculateMode = cm7Enum.gviSunCalculateMode.gviSunModeAccordingToGMT;
                for (var t = st; t < et; t += interval) {
                    var gmt = getGMTStr(new Date(t));
                    __g.sunConfig.setGMT(gmt);
                    // var ang = __g.sunConfig.getSunEuler(pt84);
                    var ang = __g.sunConfig.getSunEuler(ptTmp);
                    var sunPt = __g.camera.getAimingPoint2(ptTmp, ang, 300);
                    sunPtArr.push(sunPt);
                }
                var envPolygon = calPointsEnvelopePolygon(sunPtArr.concat(self.targetPoint));
                var curveSymbol = __g.new_CurveSymbol;
                curveSymbol.color = 0xffff00ff;
                var filter = __g.new_SpatialFilter;
                filter.geometry = envPolygon;
                filter.spatialRel = cm7Enum.gviSpatialRel.gviSpatialRelEnvelope;
                filter.geometryField = "Geometry";
                var count = 0;
                var fc_feas = [];
                for (var j = 0; j < self.fcArray.length; j++) {
                    var fc = self.fcArray[j];
                    var rows = fc.query(filter);
                    /*for (var k = 0; k < rows.length && sunPtArr.length > 0; k++) {
                        var row = rows[k];
                        // cm7.highlightJson(row);
                        var modelPoint = row.Geometry;
                        if (modelPoint.modelName) {
                            var model = fc.obj.featureDataSet.getModel(modelPoint.modelName);
                            for (var m = sunPtArr.length - 1; m >= 0; m--){
                                var p = sunPtArr[m];
                                var vector = cm7.newVector3(p.x - ptTmp.x, p.y - ptTmp.y, p.z - ptTmp.z);
                                var vecRet = modelPoint.rayIntersect(model, ptTmp, vector);
                                if (vecRet != null ) {
                                    var pl = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolyline, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                                    pl.appendPoint(ptTmp);
                                    pl.appendPoint(p);
                                    plArr.push(pl);
                                    self.renderPlArr.push(__g.objectManager.createRenderPolyline(pl, curveSymbol, __rootId));
                                    sunPtArr.splice(m, 1);
                                    console.log(0);
                                } else {
                                    var pl = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolyline, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                                    pl.appendPoint(ptTmp);
                                    pl.appendPoint(p);
                                    plArr.push(pl);
                                    self.renderPlArr.push(__g.objectManager.createRenderPolyline(pl, null, __rootId));
                                    console.log(1);
                                }
                            }
                        }
                    }*/
                    for (var item in rows) {
                        fc_feas.push({fc: fc, fea: rows[item]});
                    }
                }
                for (var item2 in sunPtArr) {
                    var p = sunPtArr[item2];
                    var vector = cm7.newVector3(p.x - ptTmp.x, p.y - ptTmp.y, p.z - ptTmp.z);
                    var covered = false;
                    for (var item3 in fc_feas) {
                        var fc = fc_feas[item3].fc;
                        var fea = fc_feas[item3].fea;
                        var modelPoint = fea.Geometry;
                        var model = fc.obj.featureDataSet.getModel(modelPoint.modelName);
                        var vector = cm7.newVector3(p.x - ptTmp.x, p.y - ptTmp.y, p.z - ptTmp.z);
                        var vecRet = modelPoint.rayIntersect(model, ptTmp, vector);
                        if (vecRet != null) {
                            covered = true;
                            break;
                        }
                    }
                    var pl = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolyline, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                    pl.appendPoint(ptTmp);
                    pl.appendPoint(p);
                    plArr.push(pl);
                    if (covered == false) {
                        // console.log(1);
                        count++
                        self.renderPlArr.push(__g.objectManager.createRenderPolyline(pl, null, __rootId));
                    } else {
                        // console.log(0);
                        self.renderPlArr.push(__g.objectManager.createRenderPolyline(pl, curveSymbol, __rootId));
                    }
                }
                // return sunPtArr.length * self.interval;
                return count * self.interval;
            } catch (e) {
                console.log(e);
            } finally {
                cm7.resumeRendering();
            }
        },
        analysis2: function () {
            try {
                cm7.pauseRendering();
                var self = this;
                var plArr = [];
                var ca = __g.camera.getCamera();
                var v0 = cm7.newVector3(ca.position.x, ca.position.y, ca.position.z);
                var v1 = cm7.newVector3(self.targetPoint.x, self.targetPoint.y, self.targetPoint.z);
                var abAng = __g.camera.getAimingAngles(v0, v1);
                var ptTmp = __g.camera.getAimingPoint2(self.targetPoint, abAng, 0.5);
                var interval = self.interval * 60 * 1000;
                /*var pt84 = ptTmp.clone();
                pt84.spatialCRS = _cmData.getSpatialCRS();
                var crs84 = __g.crsFactory.createWGS84();
                pt84.project(crs84);
                pt84.spatialCRS = crs84;*/

                var st = self.startTime.getTime();
                var et = self.endTime.getTime();

                var sunPtArr = [];
                __g.sunConfig.sunCalculateMode = cm7Enum.gviSunCalculateMode.gviSunModeAccordingToGMT;
                for (var t = st; t < et; t += interval) {
                    var gmt = getGMTStr(new Date(t));
                    __g.sunConfig.setGMT(gmt);
                    var ang = __g.sunConfig.getSunEuler(v1);
                    var sunPt = __g.camera.getAimingPoint2(ptTmp, ang, 300);
                    sunPtArr.push(sunPt);
                }
                var envPolygon = calPointsEnvelopePolygon(sunPtArr.concat(self.targetPoint));
                var curveSymbol = __g.new_CurveSymbol;
                curveSymbol.color = 0xffff00ff;
                var filter = __g.new_SpatialFilter;
                filter.geometry = envPolygon;
                filter.spatialRel = cm7Enum.gviSpatialRel.gviSpatialRelEnvelope;
                filter.geometryField = "Geometry";
                var count = 0;
                for (var j = 0; j < self.fcArray.length; j++) {
                    var fc = self.fcArray[j];
                    var rows = fc.query(filter);
                    for (var k = 0; k < rows.length && sunPtArr.length > 0; k++) {
                        var row = rows[k];
                        // cm7.highlightJson(row);
                        var modelPoint = row.Geometry;
                        if (modelPoint.modelName) {
                            var model = fc.obj.featureDataSet.getModel(modelPoint.modelName);
                            for (var m = sunPtArr.length - 1; m >= 0; m--) {
                                var p = sunPtArr[m];
                                var vector = cm7.newVector3(p.x - ptTmp.x, p.y - ptTmp.y, p.z - ptTmp.z);
                                var vecRet = modelPoint.rayIntersect(model, ptTmp, vector);
                                if (!cm7.isNull(vecRet)) {
                                    var pl = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolyline, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                                    pl.appendPoint(ptTmp);
                                    pl.appendPoint(p);
                                    plArr.push(pl);
                                    self.renderPlArr.push(__g.objectManager.createRenderPolyline(pl, curveSymbol, __rootId));
                                    sunPtArr.splice(m, 1);
                                } else {
                                    var pl = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolyline, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
                                    pl.appendPoint(ptTmp);
                                    pl.appendPoint(p);
                                    plArr.push(pl);
                                    self.renderPlArr.push(__g.objectManager.createRenderPolyline(pl, null, __rootId));
                                }
                            }
                        }
                    }
                }
                return sunPtArr.length * self.interval;
            } catch (e) {
                console.log(e);
            } finally {
                cm7.resumeRendering();
            }
        },
        clear: function () {
            var self = this;
            __g.featureManager.unhighlightAll();

            if (self.renderTargetPoint) {
                __g.objectManager.deleteObject(self.renderTargetPoint.guid);
            }
            self.renderTargetPoint = null;
            self.targetPoint = null;
            for (var i = 0; i < self.renderPlArr.length; i++) {
                if (self.renderPlArr[i]) {
                    __g.objectManager.deleteObject(self.renderPlArr[i].guid);
                }

            }
            this.renderPlArr = [];
        }

        // calSunRay: function () {
        //     var self = this;
        //     var ret = [];
        //     if (self.targetPoint) {
        //         __g.sunConfig.getSunEuler();
        //         __g.camera.getAimingPoint2(self.targetPoint.position, angle, 4000);
        //     }
        //
        //     return ret;
        // },
        // calSunRise: function (selPt) {
        //     var self = this;
        //
        //     var ca = __g.camera.getCamera();
        //     var ab =__g.camera.getAimingAngles(ca.position, selPt.position);
        //     var tarPos = __g.camera.getAimingPoint2(selPt, ab, -0.5);
        //
        //
        //     var ptTmp = tarPos.clone();
        //     ptTmp.spatialCRS = _cmData.getSpatialCRS();
        //     var crs84 = __g.crsFactory.createWGS84();
        //     ptTmp.project(crs84);
        //
        //     var date = new Date();
        //     self.calSunUpDown(date, ptTmp.x, ptTmp.y);
        //
        // },
        // calSunUpDown: function (date, m_jingdu, m_weidu) {
        //     var self = this;
        //     var declination = self.calDeclination(date);
        //     var Et = declination.Et;// 时差
        //     var ED = declination.ED;// 太阳赤纬
        //
        //     var shicha = parseInt(Et);
        //     var bhudu, bjiaodu, coszhi, hudujiao = 0;
        //
        //     bhudu = Math.PI / 180;
        //     bjiaodu = 180 / Math.PI;
        //     coszhi = -Math.tan(m_weidu * bhudu) * Math.tan(ED * bhudu);
        //
        //     if (coszhi > -1 && coszhi < -0.5) {
        //         hudujiao = Math.atan(Math.Sqrt(1 - coszhi * coszhi) / coszhi) + 4 * Math.atan(1);
        //     }
        //     if (coszhi > -0.5 && coszhi < 0.5) {
        //         hudujiao = -Math.atan(coszhi / Math.sqrt(1 - coszhi * coszhi)) + 2 * Math.atan(1);
        //     }
        //     if (coszhi > 0.5 && coszhi < 1) {
        //         hudujiao = Math.atan(Math.sqrt(1 - coszhi * coszhi) / coszhi);
        //     }
        //
        //     var jiaodujiao = hudujiao * bjiaodu;
        //
        //     var banzhouchang, n, jingdushicha;
        //
        //     n = parseInt(jiaodujiao * 4);
        //     banzhouchang = n * 4 + parseInt((jiaodujiao - n) * 4);
        //     n = parseInt(m_jingdu * 4);
        //     jingdushicha = 480 - n * 4 - parseInt((m_jingdu - n) * 4);
        //
        //     var sunupfenzhong, sundownfenzhong;
        //     sunupfenzhong = 720 - banzhouchang - shicha + jingdushicha;
        //     sundownfenzhong = 720 + banzhouchang - shicha + jingdushicha;
        //
        //     var upxiaoshi = parseInt(sunupfenzhong / 60);
        //     var upfenzhong = sunupfenzhong - upxiaoshi * 60;
        //
        //     var downxiaoshi = parseInt(sundownfenzhong / 60);
        //     var downfenzhong = sundownfenzhong - downxiaoshi * 60;
        //
        //
        //     var upDate = new Date(date);
        //     var downDate = new Date(date);
        //
        //     upDate.setHours(upxiaoshi);
        //     upDate.setMinutes(upfenzhong);
        //     downDate.setHours(downxiaoshi);
        //     downDate.setMinutes(downfenzhong);
        //
        //     return {
        //         'sunUpTime': upDate,
        //         'sunDownTime': downDate
        //     }
        //
        //
        // },
        // calYearDayCount: function (year) {
        //     if ((year % 400 === 0) || (year % 100 !== 0 && year % 4 === 0)) {
        //         return 366;
        //     }
        //     else {
        //         return 365;
        //     }
        // },
        // calDeclination: function (date) {
        //     var self = this;
        //     var ED = 0,
        //         Et = 0,
        //         N = 0,
        //         N0,
        //         QQ,
        //         m_year = date.getFullYear(),
        //         m_month = date.getMonth(),
        //         m_day = date.getDate(),
        //         daynum = self.calYearDayCount(m_year);
        //
        //     for (var i = 1; i < m_month; i++) {
        //         if (i === 1 || i === 3 || i === 5 || i === 7 || i === 8 || i === 10 || i === 12) {
        //             N += 31;
        //         }
        //         else {
        //             if (i === 4 || i === 6 || i === 9 || i === 11) {
        //                 N += 30;
        //             }
        //             else if (i === 2 && daynum === 366) {
        //                 N += 29;
        //             }
        //             else {
        //                 N += 28;
        //             }
        //         }
        //     }
        //
        //     N += m_day;
        //     N0 = 79.6764 + 0.2422 * (m_year - 1985) - parseInt((m_year - 1985) / 4);
        //     QQ = 2 * Math.PI * (N - N0) / 365.2422;
        //     ED = 0.3723 + 23.2567 * Math.sin(QQ) + 0.1149 * Math.sin(2 * QQ) - 0.1712 * Math.sin(3 * QQ) - 0.758 * Math.cos(QQ) + 0.3656 * Math.cos(2 * QQ) + 0.0201 * Math.cos(3 * QQ);
        //     Et = 0.0028 - 1.9857 * Math.sin(QQ) + 9.9059 * Math.sin(2 * QQ) - 7.0924 * Math.cos(QQ) - 0.6882 * Math.cos(2 * QQ);
        //
        //     return {
        //         'ED': ED,
        //         'Et': Et,
        //         'N': N
        //
        //     }
        //
        //
        // }

    };
    cm7.PointShadowAnalysis = function (fcArray) {
        return new PointShadowAnalysis(fcArray);
    };


///////////////////////////////////////////////////////////////////////////////
// Return: Object retVal {
//           Date SunRise,
//           Date SunSet,
//           String str    // Sun Rise, Sun Set (transformed by TimeZone)
//         };
//
//     res.str; //日出 6:48 | 正午 11:54 | 日落 17:01
//     res.strSunRise; //日出 6:48
//     res.strNoon; //正午 11:54
//     res.strSunSet; //日落 17:01
//     res.SunRise; //Date型
//     res.SunSet; //Date型
////////////////////////////////////////////////////////////////////////////////
    function computeSunRiseSunSet(Latitude, Longitude, TimeZone) {
        var curTime = new Date();
        // Variable names used: B5, C, C2, C3, CD, D, DR, H, HR, HS, L0, L5, M, MR, MS, N, PI, R1, RD, S1, SC, SD, str
        var retVal = new Object();
        var PI = Math.PI;
        var DR = PI / 180;
        var RD = 1 / DR;
        var B5 = Latitude;
        var L5 = Longitude;
        var H = -1 * (curTime.getTimezoneOffset() / 60 * -1); // Local timezone
        // Overriding TimeZone to standardize on UTC
        // H = 0;
        var M = curTime.getMonth() + 1;
        var D = curTime.getDate();
        B5 = DR * B5;
        var N = parseInt(275 * M / 9) - 2 * parseInt((M + 9) / 12) + D - 30;
        var L0 = 4.8771 + .0172 * (N + .5 - L5 / 360);
        var C = .03342 * Math.sin(L0 + 1.345);
        var C2 = RD * (Math.atan(Math.tan(L0 + C)) - Math.atan(.9175 * Math.tan(L0 + C)) - C);
        var SD = .3978 * Math.sin(L0 + C);
        var CD = Math.sqrt(1 - SD * SD);
        var SC = (SD * Math.sin(B5) + .0145) / (Math.cos(B5) * CD);
        if (Math.abs(SC) <= 1) {
            var C3 = RD * Math.atan(SC / Math.sqrt(1 - SC * SC));
            var R1 = 6 - H - (L5 + C2 + C3) / 15;
            var HR = parseInt(R1);
            var MR = parseInt((R1 - HR) * 60);
            retVal.SunRise = parseTime(HR + ":" + MR);
            var TargetTimezoneOffset = (TimeZone * 60 * 60 * 1000) + (retVal.SunRise.getTimezoneOffset() * 60 * 1000);
            var transformedSunRise = new Date(retVal.SunRise.getTime() + TargetTimezoneOffset);
            var strSunRise = "日出" + transformedSunRise.getHours() + ":" + (transformedSunRise.getMinutes() < 10 ? "0" + transformedSunRise.getMinutes() : transformedSunRise.getMinutes());
            var S1 = 18 - H - (L5 + C2 - C3) / 15;
            var HS = parseInt(S1);
            var MS = parseInt((S1 - HS) * 60);
            retVal.SunSet = parseTime(HS + ":" + MS);
            var transformedSunSet = new Date(retVal.SunSet.getTime() + TargetTimezoneOffset);
            var strSunSet = "日落" + transformedSunSet.getHours() + ":" + (transformedSunSet.getMinutes() < 10 ? "0" + transformedSunSet.getMinutes() : transformedSunSet.getMinutes());
            retVal.Noon = new Date((retVal.SunRise.getTime() + retVal.SunSet.getTime()) / 2);
            var transformedNoon = new Date(retVal.Noon.getTime() + TargetTimezoneOffset);
            var strNoon = "正午" + transformedNoon.getHours() + ":" + (transformedNoon.getMinutes() < 10 ? "0" + transformedNoon.getMinutes() : transformedNoon.getMinutes());
        }
        else {
            if (SC > 1) {
                // str="Sun up all day";
                strSunRise = ".";
                strNoon = ".";
                strSunSet = ".";
                var tDate = new Date();
                // Set Sunset to be in the future ...
                retVal.SunSet = new Date(tDate.getFullYear() + 1, tDate.getMonth(), tDate.getDay(), tDate.getHours());
                // Set Sunrise to be in the past ...
                retVal.SunRise = new Date(tDate.getFullYear() - 1, tDate.getMonth(), tDate.getDay(), tDate.getHours() - 1);
            }
            if (SC < -1) {
                // str="Sun down all day";
                strSunRise = ".";
                strNoon = ".";
                strSunSet = ".";
                // Set Sunrise and Sunset to be in the future ...
                retVal.SunRise = new Date(tDate.getFullYear() + 1, tDate.getMonth(), tDate.getDay(), tDate.getHours());
                retVal.SunSet = new Date(tDate.getFullYear() + 1, tDate.getMonth(), tDate.getDay(), tDate.getHours());
            }
        }
        retVal.strSunRise = strSunRise;
        retVal.strNoon = strNoon;
        retVal.strSunSet = strSunSet;
        retVal.str = strSunRise + ' | ' + strNoon + ' | ' + strSunSet;
        return retVal;
    }

////////////////////////////////////////////////////////////////////////////////
//
// parseTime(string aTime) - takes a string of time in the format HH:MM:SS
//                           and returns Javascript Date Object
//
////////////////////////////////////////////////////////////////////////////////
    function parseTime(aTime) {
        var aDateTimeObject = 'none';
        if (aTime !== undefined && aTime.length) {
            aDateTimeObject = GMTTime();
            try {
                var theHour = parseInt(aTime.split(':')[0]);
                var theMinutes = parseInt(aTime.split(':')[1]);
                aDateTimeObject.setHours(theHour);
                aDateTimeObject.setMinutes(theMinutes);
            }
            catch (ex) {
            }
        }
        return aDateTimeObject;
    }

////////////////////////////////////////////////////////////////////////////////
//
// GMTTime() - returns time adjusted to GMT (Universal Time)
//
////////////////////////////////////////////////////////////////////////////////
    function GMTTime() {
        var aDate = new Date();
        var aDateAdjustedToGMTInMS = aDate.getTime() + (aDate.getTimezoneOffset() * 60 * 1000);
        return (new Date(aDateAdjustedToGMTInMS));
    }

    function CutFill() {
        this.drawHelper = new DrawHelper();
        this.renderCut = null;
        this.renderFill = null;
    }

    CutFill.prototype = {
        calCutFill: function (polygon, tolerance, referenceHeight, processingFunc) {
            var callBack = null;
            if (processingFunc) {
                callBack = {
                    OnProcessing: processingFunc
                }
            } else {
                callBack = {
                    OnProcessing: function (op, ptArray) {
                    }
                }
            }
            __g.terrainAnalyse.onProcessing = callBack;
            var geometrypolygonCut = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryMultiPolygon, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            var geometrypolygonFill = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryMultiPolygon, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            var vol1 = 0, vol2 = 0;
            polygon.close();
            // var cutF = __g.terrainAnalyse.calculateCutFill(polygon, parseFloat(tolerance), parseFloat(referenceHeight), geometrypolygonCut, geometrypolygonFill, vol1, vol2);
            var cutF = __g.terrainAnalyse.calculateCutFill(polygon, parseFloat(tolerance), parseFloat(referenceHeight));
            return cutF;
        },
        drawPolygon: function () {
            var self = this;
            self.clear();
            self.drawHelper.drawPolygon(cm7Enum.gviHeightStyle.gviHeightOnTerrain);
        },
        cutFill: function (tolerance, referenceHeight, processingFunc) {
            var self = this;
            try {
                // var geometry = self.drawHelper.geometry;
                var geometry = self.drawHelper.renderGeometry.getFdeGeometry();
                if (this.renderCut) {
                    __g.objectManager.deleteObject(this.renderCut.guid);
                }
                this.renderCut = null;
                if (this.renderFill) {
                    __g.objectManager.deleteObject(this.renderFill.guid);
                }
                this.renderFill = null;
                cm7.pauseRendering();
                __g.highlightHelper.setRegion(null);
                var cutF = self.calCutFill(geometry, tolerance, referenceHeight, processingFunc);
                var ss1 = __g.new_SurfaceSymbol;
                ss1.color = 0xbbFF0000;
                self.renderCut = __g.objectManager.createRenderMultiPolygon(cutF.cutPolygon, ss1, __rootId);
                self.renderCut.heightStyle = cm7Enum.gviHeightStyle.gviHeightOnTerrain;
                var ss2 = __g.new_SurfaceSymbol;
                ss2.color = 0xbb00FF00;
                self.renderFill = __g.objectManager.createRenderMultiPolygon(cutF.fillPolygon, ss2, __rootId);
                self.renderFill.heightStyle = cm7Enum.gviHeightStyle.gviHeightOnTerrain;
                return cutF;
            } catch (ex) {
                alert('分析出错：' + ex.message);
            } finally {
                cm7.resumeRendering();
            }
        },
        clear: function () {
            this.drawHelper.clear();
            if (this.renderCut) {
                __g.objectManager.deleteObject(this.renderCut.guid);
            }
            this.renderCut = null;

            if (this.renderFill) {
                __g.objectManager.deleteObject(this.renderFill.guid);
            }
            this.renderFill = null;
        }
    };
    cm7.extend({
        CutFill: function () {
            return new CutFill();
        }
    });


    function PickModelHelper() {
    }

    PickModelHelper.prototype = {
        constructor: PickModelHelper,
        pickModel: function (func) {
            this.pick(function (pickResult, intersectPoint, mask, eventSender) {
                var fid = pickResult.featureId,
                    fl = pickResult.featureLayer,
                    fc = _cmData.getFeatureClassByGUID(fl.featureClassId),
                    row = fc.getRowById(fid);
                if (func) {
                    func(row, pickResult, intersectPoint, mask, eventSender);
                }
            })
        },
        exitPick: function () {
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
            __g.mouseSelectMode = cm7Enum.gviMouseSelectMode.gviMouseSelectClick;
            // __g.onmouseclickselect = null
            __g.calllback = {}
        },
        pick: function (func) {
            var self = this;
            var onmouseclickselect = function (pickResult, intersectPoint, mask, eventSender) {
                if (!pickResult || !intersectPoint) {
                    return;
                }
                if (func) {
                    func(pickResult, intersectPoint, mask, eventSender);
                }
            };
            __g.callback = {
                onMouseClickSelect: onmouseclickselect
            };
            __g.mouseSelectObjectMask = cm7Enum.gviMouseSelectObjectMask.gviSelectFeatureLayer;
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractSelect;
            __g.mouseSelectMode = cm7Enum.gviMouseSelectMode.gviMouseSelectClick;
            __g.highlightHelper.visibleMask = cm7Enum.gviViewportMask.gviViewAllNormalView
        }
    };
    cm7.PickModelHelper = function () {
        return new PickModelHelper();
    };


    function ModelEdit() {
        this.rowBuffer = null;
        this.renderGeo = null;
        this.dsObj = null;
        this.fc = null;
        this.flObj = null;
        this.pickResult = null;
        this.intersectPoint = null;
        this.mask = null;
        this.geo = null;
        this.editingFunc = null;
        this.undoArray = [];
        this.redoArray = [];
        this.gviGeoEditType = null;
        this.m_preGeo = null;
    }

    ModelEdit.prototype = {
        constructor: ModelEdit,
        pick: function (func) {
            var self = this;
            if ((self.rowBuffer != null || self.renderGeo != null) && self.geo) {
                var isSave = confirm('是否保存？');
                if (isSave) {
                    self.finishEdit(true);
                }
            }
            self.clear();
            var pickHelp = new PickModelHelper();
            pickHelp.pick(function (pickResult, intersectPoint, mask, eventSender) {
                if (pickResult) {
                    self.pickResult = pickResult;
                    self.intersectPoint = intersectPoint;
                    self.mask = intersectPoint;
                    switch (pickResult.type) {
                        case cm7Enum.gviObjectType.gviObjectFeatureLayer: {
                            var fid = pickResult.featureId,
                                fl = pickResult.featureLayer,
                                fc = _cmData.getFeatureClassByGUID(fl.featureClassId),
                                filter = __g.new_QueryFilter;
                            self.fc = fc;
                            self.flObj = fl;
                            filter.whereClause = "oid = " + fid;
                            var rows = fc.queryToRow(filter);
                            if (rows.length >= 1) {
                                self.rowBuffer = rows[0];
                                self.geo = self.m_preGeo = self.rowBuffer.getValue(self.rowBuffer.fieldIndex('Geometry'));
                            }
                            cm7.highlightFeature(fc.obj, fid);
                        }
                            break;
                        case cm7Enum.gviObjectType.gviObjectRenderModelPoint: {
                            self.renderGeo = pickResult.modelPoint;
                        }
                            break;
                        case cm7Enum.gviObjectType.gviObjectRenderPoint: {
                            self.renderGeo = pickResult.point;
                        }
                            break;
                        case cm7Enum.gviObjectType.gviObjectRenderPolyline: {
                            self.renderGeo = pickResult.polyline;
                        }
                            break;
                        case cm7Enum.gviObjectType.gviObjectRenderPolygon: {
                            self.renderGeo = pickResult.polygon;
                        }
                            break;
                    }
                }
                pickHelp.exitPick();
                if (func) {
                    func(pickResult, intersectPoint, mask, eventSender);
                }
            });
        },
        startEdit: function (type) {
            var self = this;
            var resultCode = false;
            __g.objectEditor.finishEdit();
            if (self.renderGeo) {
                resultCode = __g.objectEditor.startEditRenderGeometry(self.renderGeo, type);
            } else if (self.rowBuffer && self.flObj) {
                var EventCall = {
                    onObjectEditing: function (geometry) {
                        self.geo = geometry;
                        self.undoArray.push(self.m_preGeo);
                        self.redoArray = [];
                        self.m_preGeo = geometry;
                        var idx = self.rowBuffer.fieldIndex('Geometry');
                        self.rowBuffer.setValue(idx, geometry);
                        self.editingFunc(geometry);
                    },
                    onObjectEditFinish: function () {
                    }
                };
                __g.callback = EventCall;
                self.gviGeoEditType = type;
                __g.interactMode = cm7Enum.gviInteractMode.gviInteractEdit;  // 进入编辑模式，重要！！
                resultCode = __g.objectEditor.startEditFeatureGeometry(self.rowBuffer, self.flObj, type);
            } else {
                alert('请先选择编辑对象！');
                return;
            }

            if (!resultCode) {
                alert('启动编辑失败！错误代码：' + __g.getLastError());
            }
        },
        finishEdit: function (isSave) {
            var self = this,
                ret = false;
            cm7.unhighlightAll();
            __g.objectEditor.finishEdit();
            if (isSave) {
                ret = self.fc.update({oid: self.pickResult.featureId, Geometry: self.geo}, true);
            }
            self.clear();
            return ret;
        },
        undo: function () {
            var self = this;
            __g.objectEditor.finishEdit();
            if (self.undoArray.length !== 0) {
                self.redoArray.push(self.geo);
            }

            var geo = self.undoArray.pop();
            if (geo) {
                var idx = self.rowBuffer.fieldIndex('Geometry');
                self.rowBuffer.setValue(idx, geo);
                __g.featureManager.editFeature(self.fc.obj, self.rowBuffer);
                self.geo = geo;
            }
        },
        redo: function () {
            var self = this;
            __g.objectEditor.finishEdit();
            if (self.redoArray.length !== 0) {
                self.undoArray.push(self.geo);
            }

            var geo = self.redoArray.pop();
            if (geo) {
                var idx = self.rowBuffer.fieldIndex('Geometry');
                self.rowBuffer.setValue(idx, geo);
                __g.featureManager.editFeature(self.fc.obj, self.rowBuffer);
                self.geo = geo;
            }
        },
        clear: function () {
            var self = this;
            cm7.unhighlightAll();
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
            self.rowBuffer = null;
            self.renderGeo = null;
            self.dsObj = null;
            self.fc = null;
            self.flObj = null;
            self.pickResult = null;
            self.intersectPoint = null;
            self.mask = null;
            self.geo = null;
            self.undoArray = [];
            self.redoArray = [];
            __g.objectEditor.finishEdit();
        },
        del: function () {
            if (this.pickResult) {
                var fid = this.pickResult.featureId;
                this.fc.deleteRowById(fid);
                this.clear();
            }
        },
        copy: function () {
            var row = this.rowBuffer.clone(false);
            var geoPos = row.fieldIndex("Geometry");
            if (geoPos != -1) {
                var geo = row.getValue(geoPos);
                geo.z = geo.z + 30;
                row.setValue(geoPos, geo);
                this.fc.insertRow(row);
                var ret = __g.featureManager.createFeature(this.fc.obj, row);
            }
        }
    };
    cm7.ModelEdit = function () {
        return new ModelEdit();
    };


    function EditTools() {
        this.gviGeoEditType = cm7Enum.gviGeoEditType.gviGeoEdit3DMove;
        this.rowBuffer = null;
        this.featureLayer = null;
        this.renderGeo = null
    }

    EditTools.prototype = {
        constructor: EditTools,
        startEditRenderGeometry: function (currentGeometry, gviGeoEditType) {
            if (currentGeometry && gviGeoEditType) {
                __g.objectEditor.finishEdit();
                var resultCode = __g.objectEditor.startEditRenderGeometry(currentGeometry, gviGeoEditType);
                if (!resultCode) {
                    alert(resultCode.ToString())
                }
            }
        },
        startEditFeatureGeometry: function (rowBuffer, featureLayer, gviGeoEditType) {
            if (rowBuffer && featureLayer && gviGeoEditType) {
                __g.objectEditor.finishEdit();
                var resultCode = __g.objectEditor.startEditFeatureGeometry(rowBuffer, featureLayer, gviGeoEditType);
                if (!resultCode) {
                    alert(resultCode.ToString())
                }
            }
        },
        startEdit: function () {
            var self = this;
            self.startEditRenderGeometry(self.renderGeo, self.gviGeoEditType);
            self.startEditFeatureGeometry(self.rowBuffer, self.featureLayer, self.gviGeoEditType)
        },
        endEdit: function () {
            __g.objectEditor.finishEdit()
        },
        setGeoEditType: function (gviGeoEditType) {
            this.gviGeoEditType = gviGeoEditType
        },
        selectEdit: function () {
            var self = this;
            __g.onmouseclickselect = function (pickResult, intersectPoint, mask, eventSender) {
                __g.onmouseclickselect = null;
                self.rowBuffer = null;
                self.featureLayer = null;
                self.renderGeo = null;
                // cm7.unhighlightAll();
                if (pickResult) {
                    switch (pickResult.type) {
                        case cm7Enum.gviObjectType.gviObjectFeatureLayer: {
                            var fid = pickResult.featureId,
                                fl = pickResult.featureLayer,
                                fc = _cmData.getFeatureClassByGUID(fl.featureClassId),
                                filter = __g.new_QueryFilter;
                            filter.whereClause = "oid = " + fid;
                            var rows = fc.queryToRow(filter);
                            if (rows.length >= 1) {
                                self.rowBuffer = rows[0];
                            }

                            // var fid = pickResult.featureId;
                            // var fc = _cmData.getFeatureClassByGUID(fid);
                            // var featureLayer = pickResult.featureLayer;
                            // var cursor = null;
                            // var rowBuffer = null;
                            // try {
                            //     rowBuffer = fc.createRowBuffer();
                            //     var filter = __g.new_QueryFilter;
                            //     filter.whereClause = "oid =" + fid;
                            //     cursor = fc.search(filter, false);
                            //     if (cursor != null) {
                            //         var row = null;
                            //         if ((row = cursor.nextRow()) != null) {
                            //             rowBuffer = row
                            //         }
                            //         cursor.releaseObject();
                            //         cursor = null
                            //     }
                            // } catch (ex) {
                            //     alert(ex.Message)
                            // } finally {
                            //     if (cursor != null) {
                            //         cursor.releaseObject()
                            //     }
                            // }
                            // cm7.highlightFeature(fc, fid, 0xffff0000)
                            //

                        }
                            break;
                        case gviObjectType.gviObjectRenderModelPoint:
                            self.renderGeo = pickResult.modelPoint;
                            break;
                        case gviObjectType.gviObjectRenderPoint:
                            self.renderGeo = pickResult.point;
                            break;
                        case gviObjectType.gviObjectRenderPolyline:
                            self.renderGeo = pickResult.polyline;
                            break;
                        case gviObjectType.gviObjectRenderPolygon:
                            self.renderGeo = pickResult.polygon;
                            break
                    }
                    self.startEdit()
                }
            }
        },
        createPoint: function () {
            __g.objectEditor.finishEdit();
            var geoFactory = __g.geometryFactory;
            var point = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            point.setCoords(0, 0, 0, 0);
            point.spatialCRS = _cmData.getSpatialCRS();
            var symbol = __g.new_SimplePointSymbol;
            symbol.size = 10;
            var rPoint = __g.objectManager.createRenderPoint(point, symbol, __rootId);
            var ret = __g.objectEditor.startEditRenderGeometry(rPoint, cm7Enum.gviGeoEditType.gviGeoEditCreator);
            if (!ret) {
                alert(__g.getLastError())
            }
            return rPoint
        },
        createPolyline: function () {
            __g.objectEditor.finishEdit();
            var geoFactory = __g.geometryFactory;
            var polyline = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolyline, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            polyline.spatialCRS = _cmData.getSpatialCRS();
            var symbol = __g.new_SimplePointSymbol;
            symbol.size = 10;
            var rpolyline = __g.objectManager.createRenderPoint(polyline, symbol, __rootId);
            var ret = __g.objectEditor.startEditRenderGeometry(rpolyline, cm7Enum.gviGeoEditType.gviGeoEditCreator);
            if (!ret) {
                alert(__g.getLastError())
            }
            return rpolyline
        },
        createPolygon: function () {
        }
    };
    cm7.EditTools = function () {
        return new EditTools();
    };


    function DrawHelper() {
        this.geometry = null;
        this.renderGeometry = null
    }

    DrawHelper.prototype = {
        constructor: DrawHelper,
        clear: function () {
            var self = this;
            __g.objectEditor.finishEdit();
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
            __g.mouseSelectObjectMask = cm7Enum.gviMouseSelectObjectMask.gviSelectNone;
            __g.mouseSelectMode = cm7Enum.gviMouseSelectMode.gviMouseSelectClick;
            __g.highlightHelper.visibleMask = cm7Enum.gviViewportMask.gviViewAllNormalView;
            __g.highlightHelper.setRegion(null);
            // __g.onmouseclickselect = null;
            if (self.renderGeometry != null) {
                __g.objectManager.deleteObject(self.renderGeometry.guid);
                self.renderGeometry = null;
            }
            this.geometry = null;
        },
        clearRender: function () {
            var self = this;
            if (self.renderGeometry != null) {
                __g.objectManager.deleteObject(self.renderGeometry.guid);
                self.renderGeometry = null;
            }
        },
        drawPoint: function (simplePointSymbol) {
            var self = this;
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractEdit;
            __g.highlightHelper.visibleMask = cm7Enum.gviViewportMask.gviViewAllNormalView;
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractEdit;
            __g.onobjectediting = function (geometry) {
                self.geometry = geometry;
            };
            __g.onobjecteditfinish = function () {
                __g.onobjecteditfinish = null;
                __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
            };
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractEdit;
            self.geometry = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            self.geometry.setCoords(0, 0, 0, 0, 0);
            self.geometry.spatialCRS = _cmData.getSpatialCRS();
            if (!simplePointSymbol) {
                simplePointSymbol = __g.new_SimplePointSymbol;
                simplePointSymbol.size = 10;
            }
            self.renderGeometry = __g.objectManager.createRenderPoint(self.targetPoint, symbol, __rootId);
            var resultCode = __g.objectEditor.startEditRenderGeometry(self.renderTargetPoint, cm7Enum.gviGeoEditType.gviGeoEditCreator);
        },
        drawPolygon: function (gviHeightStyle, polygonCreated) {
            var self = this;
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractEdit;
            __g.highlightHelper.visibleMask = cm7Enum.gviViewportMask.gviViewAllNormalView;
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractEdit;
            var surfaceSymbol = __g.new_SurfaceSymbol;
            surfaceSymbol.color = 0x55ffff80;
            self.geometry = __g.geometryFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolygon, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            self.geometry.spatialCRS = _cmData.getSpatialCRS();
            self.renderGeometry = __g.objectManager.createRenderPolygon(self.geometry, surfaceSymbol, __rootId);
            if (gviHeightStyle) {
                self.renderGeometry.heightStyle = gviHeightStyle;
            } else {
                self.renderGeometry.heightStyle = cm7Enum.gviHeightStyle.gviHeightOnEverything;
            }
            var resultCode = __g.objectEditor.startEditRenderGeometry(self.renderGeometry, cm7Enum.gviGeoEditType.gviGeoEditCreator);

            var EventCall = {
                onObjectEditing: function (geometry) {
                    self.geometry = geometry;
                    __g.highlightHelper.setRegion(geometry);
                },
                onObjectEditFinish: function () {
                    __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
                    if (polygonCreated != null) {
                        polygonCreated();
                    }
                }
            };
            __g.callback = EventCall;

        },
        createPoint: function () {
            __g.objectEditor.finishEdit();
            var geoFactory = __g.geometryFactory;
            var point = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            point.setCoords(0, 0, 0, 0, 0);
            point.spatialCRS = _cmData.getSpatialCRS();
            var symbol = __g.new_SimplePointSymbol;
            symbol.size = 10;
            var rPoint = __g.objectManager.createRenderPoint(point, symbol, __rootId);
            var ret = __g.objectEditor.startEditRenderGeometry(rPoint, cm7Enum.gviGeoEditType.gviGeoEditCreator);
            if (!ret) {
                alert(__g.getLastError())
            }
            return rPoint
        },
        createPolyline: function () {
            __g.objectEditor.finishEdit();
            this.geometry = null;
            this.renderGeometry = null;
            __g.interactMode = cm7Enum.gviInteractMode.gviInteractEdit;
            var geoFactory = __g.geometryFactory;
            this.geometry = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPolyline, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            this.geometry.spatialCRS = _cmData.getSpatialCRS();
            this.renderGeometry = __g.objectManager.createRenderPolyline(this.geometry, null, __rootId);
            var ret = __g.objectEditor.startEditRenderGeometry(this.renderGeometry, cm7Enum.gviGeoEditType.gviGeoEditCreator);
            if (!ret) {
                alert(__g.getLastError())
            }
            var EventCall = {
                onObjectEditing: function (geometry) {
                    self.geometry = geometry;
                },
                onObjectEditFinish: function () {
                    __g.interactMode = cm7Enum.gviInteractMode.gviInteractNormal;
                }
            };
            __g.callback = EventCall;
        },
    };
    cm7.DrawHelper = function () {
        return new DrawHelper();
    };


    function AttachmentHelper(fcObj) {
        this.fcObj = fcObj
    }

    AttachmentHelper.prototype = {
        constructor: AttachmentHelper,
        addAttachment: function (file, fid) {
            var self = this;
            var reader = new FileReader();
            reader.readAsText(file, "utf-8");
            reader.onload = function (e) {
                try {
                    var mgr = self.fcObj.getAttachmentManager();
                    var base64Code = e.target.result;
                    var am = __g.new_Attachment;
                    var bb = __g.new_BinaryBuffer;
                    bb.fromString(base64Code);
                    am.name = 'fName';
                    am.featureId = fid;
                    am.mimeType = "text/xml";
                    am.data = bb;
                    mgr.addAttachment(am)
                } catch (e) {
                }
            }
        },
        getAttachmentInfo: function () {
        },
        getAttachment: function () {
        },
        disableAttachment: function () {
            this.fcObj.disableAttachment()
        },
        readText: function (file) {
            var reader = new FileReader();
            reader.readAsText(file, "utf-8");
            reader.onload = function (e) {
                console.log("加载成功")
                base64Code = e.target.result
            }
            reader.onloadstart = function () {
                console.log("开始加载")
            }
            reader.onloadend = function () {
                console.log("加载结束")
            }
            reader.onprogress = function () {
                console.log("加载中" + count)
            }
        }
    };
    cm7.AttachmentHelper = function () {
        return new AttachmentHelper();
    };

    function GeometryConvert() {
    }

    GeometryConvert.prototype = {
        constructor: GeometryConvert,
        modelPointToTriMesh: function (fcObj, geo, isUseTexture) {
            var model = cm7.getModel(fcObj, geo);
            return model ? __g.geometryConvertor.modelPointToTriMesh(geo, model, isUseTexture) : null;
        },
        //三角网格面集合转化为Model和ModelPoint。
        triMeshToModelPoint: function (multiTM) {
            return __g.geometryConvertor.triMeshToModelPoint(multiTM);
        },

        multiTriMeshToMultiPoint: function (multiTM, tol) {
            return __g.geometryConvertor.multiTriMeshToMultiPoint(multiTM, tol);
        },

        projectTriMeshToPolygon: function (multiTM, tol) {
            return __g.geometryConvertor.projectTriMeshToPolygon(multiTM, tol);
        },
        projectTrimeshToXYPlane: function (multiTM) {
            return __g.geometryConvertor.projectTrimeshToXYPlane(multiTM);
        },
        projectModelPointToXYPlane: function (multiTM) {
            return __g.geometryConvertor.projectModelPointToXYPlane(multiTM);
        },
        //（推荐）计算ModelPoint在z=0平面上的二维投影。
        projectModelPointToPolygon: function (fcObj, geo, tol) {
            var model = cm7.getModel(fcObj, geo);
            return model ? __g.geometryConvertor.projectModelPointToPolygon(geo, model, tol) : null;
        },
        //Polygon转换成Model+ModelPoint.
        polygonToModelPoint: function (polygon) {
            return __g.geometryConvertor.polygonToModelPoint(polygon);
        },
        //多边形三角化。
        polygonToTriMesh: function (polygon) {
            return __g.geometryConvertor.polygonToTriMesh(polygon);
        },

        //多边形拉成建筑。
        extrudePolygonToModel: function (Polygon, FloorNumber, FloorHeight, SlopeAngle, RoofType, FacadeTextureName, RoofTextureName) {
            return __g.geometryConvertor.extrudePolygonToModel(Polygon, FloorNumber, FloorHeight, SlopeAngle, RoofType, FacadeTextureName, RoofTextureName);
        },
        //多边形拉成体块。
        extrudePolygonToTriMesh: function (Polygon, Height, Closed) {
            return __g.geometryConvertor.extrudePolygonToTriMesh(Polygon, Height, Closed);
        },
        //推荐）计算三角网格面集合在指定高度平面（切割面）上的二维投影。
        cutTriMeshToPolygon: function (multiTM, heightSpec, tol) {
            return __g.geometryConvertor.cutTriMeshToPolygon(multiTM, heightSpec, tol);
        },
        //用多边形带高度限制地切割建筑。
        cutModelPointByPolygon2DWithZ: function (MultiPolygon, ModelSrc, ModelPointSrc, MinZ, MaxZ, Model, ModelPoint) {
            return __g.geometryConvertor.cutModelPointByPolygon2DWithZ(MultiPolygon, ModelSrc, ModelPointSrc, MinZ, MaxZ, Model, ModelPoint);
        },
        //简化模型
        simplifyModel: function (model) {
            return __g.geometryConvertor.simplifyModel(model);
        },
        // //用带洞多边形去切割建筑。
        // SplitModelPointByPolygon2D:function () {
        //
        // },
        // //用多边形带高度限制地切割建筑。
        // SplitModelPointByPolygon2DWithZ:function () {
        //
        // },
    };
    cm7.GeometryConvert = function () {
        return new GeometryConvert();
    };


    function CoordConvert() {
    }

    CoordConvert.prototype = {
        constructor: CoordConvert,
        chooseCoordSysDlg: function () {
            var coordSys = __g.coordSysDialog.showDialog(0);
            return coordSys
        },
        convert: function (srcPoint, srcWkt, tarWkt) {
            var geoFactory = __g.geometryFactory,
                srcCRS = __g.crsFactory.createFromWKT(srcWkt),
                tarCRS = __g.crsFactory.createFromWKT(tarWkt)
            point = geoFactory.createGeometry(cm7Enum.gviGeometryType.gviGeometryPoint, cm7Enum.gviVertexAttribute.gviVertexAttributeZ);
            point.spatialCRS = srcCRS;
            point.setCoords(srcPoint.x, srcPoint.y, srcPoint.z, 0, 0);
            var isOk = point.project(tarCRS);
            if (isOk) {
                return point
            } else {
                return null
            }
        },
        getCRSWkt: function () {
        }
    };
    cm7.CoordConvert = function () {
        return new CoordConvert()
    };


    function getBroswerLocation(func) {
        if (navigator.geolocation) {
            var showError = function (error) {
                switch (error.code) {
                    case error.PERMISSION_DENIED:
                        alert("User denied the request for Geolocation.");
                        break;
                    case error.POSITION_UNAVAILABLE:
                        alert("Location information is unavailable.");
                        break;
                    case error.TIMEOUT:
                        alert("The request to get user location timed out.");
                        break;
                    case error.UNKNOWN_ERROR:
                        alert("An unknown error occurred.");
                        break
                }
            };
            navigator.geolocation.getCurrentPosition(func, showError)
        } else {
            alert("当前浏览器不支持定位。")
        }
    }

    function mapLocation(srcWkt, tarWkt) {
        getBroswerLocation(function (pos) {
            var coordConvert = new CoordConvert();
            var srcPoint = {
                x: pos.coords.longitude,
                y: pos.coords.latitude,
                z: 0
            };
            var tarPoint = coordConvert.convert(srcPoint, srcWkt, tarWkt);
            setCamera(tarPoint.x, tarPoint.y, tarPoint.z, 0, -90, 0)
        })
    }


    function LocalFileTool() {
    }

    LocalFileTool.prototype = {
        constructor: LocalFileTool,
        writeTxtFile: function (path, str) {
            var fso = new ActiveXObject("Scripting.FileSystemObject");
            var file = fso.CreateTextFile(path, true, true);
            file.WriteLine(str);
            file.close()
        },
        readTxtFile: function (path) {
            var fso = new ActiveXObject("Scripting.FileSystemObject");
            var file = fso.OpenTextFile(path, 1, true);
            var str = file.ReadAll();
            file.close();
            return str
        }
    };
    cm7.LocalFileTool = function () {
        return new LocalFileTool();
    };


    function ClearHelper() {
        this.callFunc = {};
    }

    ClearHelper.prototype = {
        constructor: ClearHelper,
        addClearFunc: function (name, func) {
            this.callFunc[name] = func;
        },
        getClearFunc: function (name) {
            return this.callFunc[name];
        },
        delClearFunc: function (name) {
            this.callFunc[name] = null;
            delete this.callFunc[name];
        },
        clearAll: function () {
            if (!this.callFunc) {
                return;
            }
            for (var fu in this.callFunc) {
                try {
                    this.callFunc[fu]();
                } catch (e) {
                    console.error('error when clear function:' + fu + ' error info: ' + e.message);
                }
            }
            cm7.panMove();
        }
    };


    var cm7Enum = {
        geodeticCoordinateSystem: {
            GCS_CGCS_2000: 'GEOGCS["GCS_China_Geodetic_Coordinate_System_2000",DATUM["D_China_2000",SPHEROID["CGCS2000",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433],AUTHORITY["EPSG","4490"]]',
            GCS_Beijing_1954: 'GEOGCS["GCS_Beijing_1954",DATUM["D_Beijing_1954",SPHEROID["Krasovsky_1940",6378245.0,298.3]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433],AUTHORITY["EPSG","4214"]]',
            GCS_WGS_1984: 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433],AUTHORITY["EPSG","4326"]]',
            GCS_Xian_1980: 'GEOGCS["GCS_Xian_1980",DATUM["D_Xian_1980",SPHEROID["Xian_1980",6378140.0,298.257]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433],AUTHORITY["EPSG","4610"]]'
        },
        projectedCoordinateSystem: {
            GK_Beijing_1954: 'PROJCS["Beijing_1954_3_Degree_GK_CM_102E",GEOGCS["GCS_Beijing_1954",DATUM["D_Beijing_1954",SPHEROID["Krasovsky_1940",6378245.0,298.3]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",500000],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",102],PARAMETER["Scale_Factor",1],PARAMETER["Latitude_Of_Origin",0],UNIT["metre",1]]',
            GK_Xian_1980: 'PROJCS["Xian_1980_3_Degree_GK_CM_120E",GEOGCS["GCS_Xian_1980",DATUM["D_Xian_1980",SPHEROID["Xian_1980",6378140.0,298.257]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",500000],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",120],PARAMETER["Scale_Factor",1],PARAMETER["Latitude_Of_Origin",0],UNIT["metre",1]]',
            GK_CGCS_2000: 'PROJCS["CGCS_2000_3_Degree_GK_CM_120E",GEOGCS["GCS_China_Geodetic_Coordinate_System_2000",DATUM["D_China_2000",SPHEROID["CGCS2000",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",500000],PARAMETER["False_Northing",0],PARAMETER["Central_Meridian",120],PARAMETER["Scale_Factor",1],PARAMETER["Latitude_Of_Origin",0],UNIT["metre",1]]'
        },
        projectCompareLookAngle: {
            "north": 180,
            "eastnorth": 225,
            "east": 270,
            "eastsouth": 315,
            "south": 0,
            "westsouth": 45,
            "west": 90,
            "westnorth": 135
        },
        gviLanguage: {
            gviLanguageChineseSimple: 0,
            gviLanguageChineseTraditional: 1,
            gviLanguageEnglish: 2
        },
        gviFieldType: {
            gviFieldUnknown: 0,
            gviFieldInt16: 2,
            gviFieldInt32: 3,
            gviFieldInt64: 4,
            gviFieldFloat: 5,
            gviFieldDouble: 6,
            gviFieldString: 7,
            gviFieldDate: 8,
            gviFieldBlob: 9,
            gviFieldFID: 10,
            gviFieldUUID: 11,
            gviFieldGeometry: 99
        },
        gviDomainType: {
            gviDomainRange: 0,
            gviDomainCodedValue: 1
        },
        gviGeometryColumnType: {
            gviGeometryColumnPoint: 0,
            gviGeometryColumnModelPoint: 1,
            gviGeometryColumnPOI: 2,
            gviGeometryColumnMultiPoint: 3,
            gviGeometryColumnPolyline: 4,
            gviGeometryColumnPolygon: 5,
            gviGeometryColumnTriMesh: 7,
            gviGeometryColumnPointCloud: 8,
            gviGeometryColumnCollection: 9,
            gviGeometryColumnUnknown: -1
        },
        gviIndexType: {
            gviIndexRdbms: 0,
            gviIndexGrid: 3,
            gviIndexRender: 4
        },
        gviDataSetType: {
            gviDataSetAny: 0,
            gviDataSetDbmsTable: 1,
            gviDataSetObjectClassTable: 2,
            gviDataSetFeatureClassTable: 3
        },
        gviFilterType: {
            gviFilterAttributeOnly: 1,
            gviFilterWithSpatial: 2,
            gviFilterWithTemporal: 3
        },
        gviConnectionType: {
            gviConnectionUnknown: 0,
            gviConnectionMySql5x: 2,
            gviConnectionFireBird2x: 3,
            gviConnectionOCI11: 4,
            gviConnectionPg9: 5,
            gviConnectionMSClient: 6,
            gviConnectionSQLite3: 10,
            gviConnectionShapeFile: 12,
            gviConnectionArcGISServer10: 13,
            gviConnectionArcSDE9x: 14,
            gviConnectionArcSDE10x: 15,
            gviConnectionWFS: 16,
            gviConnectionKingBase7: 17,
            gviConnectionCms7Http: 101,
            gviConnectionCms7Https: 102,
            gviConnectionPlugin: 999
        },
        gviLockType: {
            gviLockSharedSchemaReadonly: 0,
            gviLockSharedSchema: 1,
            gviLockExclusiveSchema: 2
        },
        gviSpatialRel: {
            gviSpatialRelEnvelope: 0,
            gviSpatialRelEquals: 1,
            gviSpatialRelIntersects: 2,
            gviSpatialRelTouches: 3,
            gviSpatialRelCrosses: 4,
            gviSpatialRelWithin: 5,
            gviSpatialRelContains: 6,
            gviSpatialRelOverlaps: 7
        },
        gviRenderIndexRebuildType: {
            gviRenderIndexRebuildFlagOnly: 1,
            gviRenderIndexRebuildWithData: 2
        },
        gviNetworkAttributeUsageType: {
            gviUseAsCost: 0,
            gviUseAsDescriptor: 1,
            gviUseAsRestriction: 2,
            gviUseAsHierarchy: 3
        },
        gviNetworkElementType: {
            gviJunction: 1,
            gviEdge: 2
        },
        gviEvaluatorType: {
            gviConstantEvaluator: 0,
            gviFieldEvaluator: 1,
            gviScriptEvaluator: 2
        },
        gviEdgeDirection: {
            gviNone: 0,
            gviAlongDigitized: 1,
            gviAgainstDigitized: 2
        },
        gviNetworkType: {
            gviDirectedNetwork: 0,
            gviUnDirectedNetwork: 1
        },
        gviNetworkElevationModel: {
            gviElevationNone: 0,
            gviElevationFields: 1,
            gviZCoordinates: 2
        },
        gviNetworkBarrierType: {
            gviJunctionBarrier: 1,
            gviEdgeBarrier: 2
        },
        gviConstraintBarrierType: {
            gviRestriction: 0,
            gviAddedCost: 1
        },
        gviNetworkLocationType: {
            gviLocation: 1,
            gviEventLocation: 2
        },
        gviNetworkLocationOrderPolicy: {
            gviSequence: 1,
            gviFixStart: 2,
            gviFixStartAndReturn: 3,
            gviFixStartEnd: 4,
            gviFree: 5
        },
        gviFdbCapability: {
            gviFdbCapReplicationCheckOutMaster: 1,
            gviFdbCapQueryResultIndexRange: 2,
            gviFdbCapModifyField: 3,
            gviFdbCapAddField: 4,
            gviFdbCapDeleteField: 5,
            gviFdbCapModifyData: 20
        },
        gviResultStoreLocation: {
            gviResultStoreLocationServer: 0,
            gviResultStoreLocationClient: 1
        },
        gviNameType: {
            gviNameDataSource: 0,
            gviNameFeatureDataSet: 1,
            gviNameTable: 2,
            gviNameObjectClass: 3,
            gviNameFeatureClass: 4,
            gviNameFieldInfo: 5,
            gviNameResource: 6,
            gviNameIndex: 7
        },
        gviReplicateOperation: {
            gviReplicateInitialize: 0,
            gviReplicateFinished: 1,
            gviReplicateExtractSchema: 2,
            gviReplicateExtractData: 3,
            gviReplicateCreateSchema: 4,
            gviReplicateReplicateData: 5,
            gviReplicateCreateSpatialIndex: 6,
            gviReplicateCreateRenderIndex: 7,
            gviReplicateCommitTransaction: 8,
            gviReplicateTruncateDelta: 9,
            gviReplicateReleaseLock: 10,
            gviCloseFile: 11,
            gviWriteFile: 12,
            gviOpenFile: 13,
            gviWriteImage: 14,
            gviWriteModel: 15
        },
        gviNetworkJunctionConnectivityPolicy: {
            gviHonor: 1,
            gviOverride: 2
        },
        gviNetworkEdgeConnectivityPolicy: {
            gviAnyVertex: 1,
            gviEndVertex: 2
        },
        gviConflictDetectedType: {
            gviConflictDetectedMaster: 1,
            gviConflictDetectedSlave: 2,
            gviConflictDetectedManual: 3
        },
        gviReplicationType: {
            gviReplicationCheckOut: 0,
            gviReplicationCheckIn: 1
        },
        gviModelLODType: {
            gviSimpleModel: 0,
            gviFineModel: 1
        },
        gviNetworkSide: {
            gviSideNone: 0,
            gviSideAlongDigitized: 1,
            gviSideAgainstDigitized: 2
        },
        gviDataConnectionType: {
            gviOgrConnectionUnknown: 0,
            gviOgrConnectionDWG: 1,
            gviOgrConnectionShp: -2147483647,
            gviOgrConnectionSDE: -2147483646,
            gviOgrConnectionOCI: -2147483645,
            gviOgrConnectionMS: -2147483644,
            gviOgrConnectionPG: -2147483643,
            gviOgrConnectionPGEO: -2147483642,
            gviOgrConnectionWFS: -2147483641,
            gviOgrConnectionFileGDB: -2147483640,
            gviOgrConnectionSKP: -2147483639,
            gviOgrConnectionLAS: -2147483632,
            gviOgrConnectionFBX: -2147483631,
            gviOgrConnectionIFC: -2147483628
        },
        gviResourceConflictPolicy: {
            gviResourceIgnore: 1,
            gviResourceUserExists: 2,
            gviResourceOverWrite: 3,
            gviResourceRenameToNew: 4
        },
        gviDomainCopyPolicy: {
            gviDomainIgnor: 1,
            gviDomainCopy: 2
        },
        gviRebuildRenderIndexPolicy: {
            gviRebuildNone: 1,
            gviRebuildOnlyFlag: 2,
            gviRebuildWithData: 3
        },
        gviRasterConnectionType: {
            gviRasterConnectionUnknown: 0,
            gviRasterConnectionFile: 1,
            gviRasterConnectionWMS: 2,
            gviRasterConnectionOCI: 3,
            gviRasterConnectionWMTS: 4,
            gviRasterConnectionMapServer: 5
        },
        gviGeometryType: {
            gviGeometryUnknown: 0,
            gviGeometryPoint: 1,
            gviGeometryModelPoint: 2,
            gviGeometryPOI: 4,
            gviGeometryCircularArc: 6,
            gviGeometryLine: 10,
            gviGeometryCircle: 11,
            gviGeometryPolyline: 30,
            gviGeometryRing: 31,
            gviGeometryCompoundLine: 32,
            gviGeometryPolygon: 50,
            gviGeometryTriMesh: 51,
            gviGeometryCollection: 70,
            gviGeometryMultiPoint: 71,
            gviGeometryMultiPolyline: 72,
            gviGeometryMultiPolygon: 73,
            gviGeometryMultiTrimesh: 74,
            gviGeometryClosedTriMesh: 77,
            gviGeometryPointCloud: 100
        },
        gviGeometryDimension: {
            gviGeometry0Dimension: 0,
            gviGeometry1Dimension: 1,
            gviGeometry2Dimension: 2,
            gviGeometry3Dimension: 3,
            gviGeometryNoDimension: -1
        },
        gviVertexAttribute: {
            gviVertexAttributeNone: 0,
            gviVertexAttributeZ: 1,
            gviVertexAttributeM: 2,
            gviVertexAttributeZM: 3,
            gviVertexAttributeID: 4,
            gviVertexAttributeZID: 5,
            gviVertexAttributeMID: 6,
            gviVertexAttributeZMID: 7
        },
        gviCoordinateReferenceSystemType: {
            gviCrsProject: 1,
            gviCrsGeographic: 2,
            gviCrsVertical: 3,
            gviCrsTemporal: 4,
            gviCrsUnknown: 5,
            gviCrsENU: 6
        },
        gviCurveInterpolationType: {
            gviCurveInterpolationLinear: 0,
            gviCurveInterpolationCircle: 1
        },
        gviLocateStatus: {
            gviLocateOutside: 0,
            gviLocateVertex: 1,
            gviLocateEdge: 2,
            gviLocateFacet: 3
        },
        gviSurfaceInterpolationType: {
            gviSurfaceInterpolationPlanar: 0,
            gviSurfaceInterpolationSpherical: 1,
            gviSurfaceInterpolationElliptical: 2,
            gviSurfaceInterpolationParametricCurve: 3
        },
        gviTerrainAnalyseOperation: {
            gviTerrainGetSurfaceArea: 0,
            gviTerrainFindWaterSinkBoundary: 1,
            gviTerrainCalculateCutFill: 2
        },
        gviBufferStyle: {
            gviBufferCapround: 1,
            gviBufferCapbutt: 2,
            gviBufferCapsquare: 3
        },
        gviRoofType: {
            gviRoofFlat: 0,
            gviRoofHip: 1,
            gviRoofGable: 2
        },
        gviCommandType: {
            gviCommandStart: 0,
            gviCommandInsert: 1,
            gviCommandDelete: 2,
            gviCommandUpdate: 3
        },
        gviRenderSystem: {
            gviRenderD3D: 0,
            gviRenderOpenGL: 1
        },
        gviObjectType: {
            gviObjectNone: 0,
            gviObjectReferencePlane: 2,
            gviObjectFeatureLayer: 256,
            gviObjectTerrain: 257,
            gviObjectRenderModelPoint: 258,
            gviObjectTerrainRoute: 260,
            gviObjectRenderPolyline: 261,
            gviObjectRenderPolygon: 262,
            gviObjectRenderTriMesh: 263,
            gviObjectRenderMultiPoint: 264,
            gviObjectRenderPoint: 265,
            gviObjectCameraTour: 266,
            gviObjectMotionPath: 267,
            gviObjectSkyBox: 271,
            gviObjectParticleEffect: 272,
            gviObjectLabel: 273,
            gviObjectTableLabel: 274,
            gviObjectSkinnedMesh: 275,
            gviObjectRenderArrow: 276,
            gviObjectRenderMultiPolyline: 277,
            gviObjectRenderMultiPolygon: 278,
            gviObjectImageryLayer: 279,
            gviObjectRenderMultiTriMesh: 280,
            gviObjectTerrainHole: 281,
            gviObject3DTileLayer: 282,
            gviObjectTerrainVideo: 283,
            gviObjectOverlayLabel: 284,
            gviObjectDynamicObject: 286,
            gviObjectTerrainModifier: 287,
            gviObjectRenderPointCloud: 288,
            gviObjectRenderPOI: 289,
            gviObjectWalkGround: 290,
            gviObject3DTileHole: 291,
            gviObjectTerrainRegularPolygon: 293,
            gviObjectTerrainCylinder: 294,
            gviObjectTerrainCone: 295,
            gviObjectTerrainArrow: 296,
            gviObjectTerrain3DArrow: 297,
            gviObjectTerrainLocation: 298,
            gviObjectTerrainRectangle: 299,
            gviObjectTerrainBox: 300,
            gviObjectTerrainPyramid: 301,
            gviObjectTerrainEllipse: 302,
            gviObjectTerrainArc: 303,
            gviObjectTerrainSphere: 304,
            gviObjectPresentation: 305,
            gviObjectTerrainImageLabel: 306,
            gviObjectComplexParticleEffect: 307,
            gviObjectViewshed: 308,
            gviObjectHeatMap: 309,
            gviObjectClipPlaneOperation: 310
        },
        gviMeasurementMode: {
            gviMeasureAerialDistance: 0,
            gviMeasureHorizontalDistance: 1,
            gviMeasureVerticalDistance: 2,
            gviMeasureCoordinate: 3,
            gviMeasureGroundDistance: 4,
            gviMeasureArea: 5,
            gviMeasureGroundArea: 6,
            gviMeasureGroupSightLine: 7
        },
        gviClipMode: {
            gviClipCustomePlane: 0,
            gviClipBox: 1
        },
        gviClipPlaneOperation: {
            gviSingleClipOperation: 0,
            gviBoxClipOperation: 1
        },
        gviInteractMode: {
            gviInteractNormal: 1,
            gviInteractSelect: 2,
            gviInteractMeasurement: 3,
            gviInteractEdit: 4,
            gviInteractWalk: 5,
            gviInteractDisable: 6,
            gviInteract2DMap: 7,
            gviInteractSlide: 10,
            gviInteractClipPlane: 11,
            gviInteractFocus: 12
        },
        gviEditorType: {
            gviEditorNone: 0,
            gviEditorMove: 1,
            gviEditorRotate: 2,
            gviEditorScale: 3,
            gviEditorZRotate: 4,
            gviEditorZScale: 5,
            gviEditorZMove: 6,
            gviEditorXYMove: 7,
            gviEditorBoxScale: 8
        },
        gviMouseSelectObjectMask: {
            gviSelectNone: 0,
            gviSelectFeatureLayer: 1,
            gviSelectTerrain: 2,
            gviSelectReferencePlane: 8,
            gviSelectTerrainHole: 16,
            gviSelectTileLayer: 32,
            gviSelectLable: 64,
            gviSelectParticleEffect: 128,
            gviSelectRenderGeometry: 256,
            gviSelectSkinnedMesh: 512,
            gviSelectTileHole: 1024,
            gviSelectOverlayLabel: 2048,
            gviSelectTerrainObject: 4096,
            gviSelectTerrainVideo: 16384,
            gviSelectAll: 65535
        },
        gviMouseSelectMode: {
            gviMouseSelectClick: 1,
            gviMouseSelectDrag: 2,
            gviMouseSelectMove: 4,
            gviMouseSelectHover: 8
        },
        gviSetCameraFlags: {
            gviSetCameraNoFlags: 0,
            gviSetCameraIgnoreX: 1,
            gviSetCameraIgnoreY: 2,
            gviSetCameraIgnoreZ: 4,
            gviSetCameraIgnorePosition: 7,
            gviSetCameraIgnoreYaw: 8,
            gviSetCameraIgnorePitch: 16,
            gviSetCameraIgnoreRoll: 32,
            gviSetCameraIgnoreOrientation: 56
        },
        gviGetElevationType: {
            gviGetElevationFromDatabase: 0,
            gviGetElevationFromMemory: 1
        },
        gviPivotAlignment: {
            gviPivotAlignBottomLeft: 0,
            gviPivotAlignBottomCenter: 1,
            gviPivotAlignBottomRight: 2,
            gviPivotAlignCenterLeft: 3,
            gviPivotAlignCenterCenter: 4,
            gviPivotAlignCenterRight: 5,
            gviPivotAlignTopLeft: 6,
            gviPivotAlignTopCenter: 7,
            gviPivotAlignTopRight: 8
        },
        gviDashStyle: {
            gviDashTiny: -1717986919,
            gviDashDots: -1431655766,
            gviDashSmall: -1010580541,
            gviDashMedium: -267390961,
            gviDashLarge: -16776961,
            gviDashDot: -16678657,
            gviDashDotDot: -15978241,
            gviDashXLarge: -1044481,
            gviDashSolid: -1
        },
        gviMultilineJustification: {
            gviMultilineLeft: 0,
            gviMultilineCenter: 1,
            gviMultilineRight: 2
        },
        gviCameraTourMode: {
            gviCameraTourLinear: 0,
            gviCameraTourSmooth: 1,
            gviCameraTourBounce: 2
        },
        gviSimplePointStyle: {
            gviSimplePointCircle: 0,
            gviSimplePointSquare: 1,
            gviSimplePointCross: 2,
            gviSimplePointX: 3,
            gviSimplePointDiamond: 4
        },
        gviViewportMode: {
            gviViewportSinglePerspective: 1,
            gviViewportStereoAnaglyph: 2,
            gviViewportStereoQuadbuffer: 3,
            gviViewportL1R1: 4,
            gviViewportT1B1: 6,
            gviViewportL1M1R1: 7,
            gviViewportT1M1B1: 8,
            gviViewportL2R1: 9,
            gviViewportL1R2: 10,
            gviViewportQuad: 11,
            gviViewportPIP: 12,
            gviViewportQuadH: 13,
            gviViewportStereoDualView: 14,
            gviViewportL1R1SingleFrustum: 15,
            gviViewportT1B1SingleFrustum: 16,
            gviViewportStereoDualOculus: 17
        },
        gviSkyboxImageIndex: {
            gviSkyboxImageFront: 0,
            gviSkyboxImageBack: 1,
            gviSkyboxImageLeft: 2,
            gviSkyboxImageRight: 3,
            gviSkyboxImageTop: 4,
            gviSkyboxImageBottom: 5
        },
        gviGeoEditType: {
            gviGeoEditCreator: 0,
            gviGeoEdit3DMove: 1,
            gviGeoEdit3DRotate: 2,
            gviGeoEdit3DScale: 3,
            gviGeoEdit2DMove: 4,
            gviGeoEditZRotate: 5,
            gviGeoEditZScale: 6,
            gviGeoEditVertex: 7,
            gviGeoEditBoxScale: 8
        },
        gviParticleBillboardType: {
            gviParticleBillboardOrientedCamera: 0,
            gviParticleBillboardOrientedMoveDirection: 1
        },
        gviEmitterType: {
            gviEmitterNone: 0,
            gviEmitterPoint: 1,
            gviEmitterBox: 2,
            gviEmitterCircle: 3
        },
        gviWeatherType: {
            gviWeatherSunShine: 0,
            gviWeatherLightRain: 1,
            gviWeatherModerateRain: 2,
            gviWeatherHeavyRain: 3,
            gviWeatherLightSnow: 4,
            gviWeatherModerateSnow: 5,
            gviWeatherHeavySnow: 6
        },
        gviModKeyMask: {
            gviModKeyShift: 3,
            gviModKeyCtrl: 12,
            gviModKeyDblClk: 16384
        },
        gviViewportMask: {
            gviViewNone: 0,
            gviView0: 1,
            gviView1: 2,
            gviView2: 4,
            gviView3: 8,
            gviViewAllNormalView: 15,
            gviViewPIP: 16
        },
        gviRenderRuleType: {
            gviRenderRuleRange: 0,
            gviRenderRuleUniqueValues: 1
        },
        gviHeightStyle: {
            gviHeightOnTerrain: 0,
            gviHeightAbsolute: 1,
            gviHeightRelative: 2,
            gviHeightOnEverything: 3
        },
        gviFogMode: {
            gviFogNone: 0,
            gviFogExp: 1,
            gviFogExp2: 2,
            gviFogLinear: 3
        },
        gviRenderType: {
            gviRenderSimple: 0,
            gviRenderValueMap: 1,
            gviRenderToolTip: 2
        },
        gviRasterSourceType: {
            gviRasterUnknown: 0,
            gviRasterSourceFile: 1,
            gviRasterSourceGeoRaster: 2,
            gviRasterSourceWMS: 3,
            gviRasterSourceWMTS: 4,
            gviRasterSourceMapServer: 5
        },
        gviGeometrySymbolType: {
            gviGeoSymbolPoint: 0,
            gviGeoSymbolImagePoint: 1,
            gviGeoSymbolModelPoint: 2,
            gviGeoSymbolCurve: 3,
            gviGeoSymbolSurface: 4,
            gviGeoSymbol3DPolygon: 5,
            gviGeoSymbolSolid: 6,
            gviGeoSymbolPointCloud: 7
        },
        gviFlyMode: {
            gviFlyArc: 0,
            gviFlyLinear: 1
        },
        gviActionCode: {
            gviActionFlyTo: 0,
            gviActionJump: 1,
            gviActionFollowBehind: 2,
            gviActionFollowAbove: 3,
            gviActionFollowBelow: 4,
            gviActionFollowLeft: 5,
            gviActionFollowRight: 6,
            gviActionFollowBehindAndAbove: 7,
            gviActionFollowCockpit: 8
        },
        gviHTMLWindowPosition: {
            gviWinPosUserDefined: 0,
            gviWinPosCenterParent: 1,
            gviWinPosCenterDesktop: 2,
            gviWinPosMousePosition: 3,
            gviWinPosParentSize: 4,
            gviWinPosParentRightTop: 5
        },
        gviSunCalculateMode: {
            gviSunModeFollowCamera: 1,
            gviSunModeAccordingToGMT: 2,
            gviSunModeUserDefined: 3
        },
        gviMouseSnapMode: {
            gviMouseSnapDisable: 0,
            gviMouseSnapVertex: 1
        },
        gviArrowType: {
            gviArrowSingle: 0,
            gviArrowDual: 1
        },
        gviCollisionDetectionMode: {
            gviCollisionDisable: 0,
            gviCollisionOnlyKeyboard: 1,
            gviCollisionEnable: 3
        },
        gviAttributeMask: {
            gviAttributeHighlight: 1,
            gviAttributeCollision: 2,
            gviAttributeClipPlane: 4
        },
        gviRenderControlParameters: {
            gviRenderParamMeasurementLengthUnit: 0,
            gviRenderParamMeasurementAreaUnit: 1,
            gviRenderParamLanguage: 2,
            gviRenderParamLight0Ambient: 3,
            gviRenderParamLight0Diffuse: 4,
            gviRenderParamLightModelAmbient: 5,
            gviRenderParamStereoFusionDistance: 6,
            gviRenderParamStereoEyeSeparation: 7,
            gviRenderParamStereoScreenDistance: 8,
            gviRenderParam3DWindowHeight: 9,
            gviRenderParam3DWindowWidth: 10,
            gviRenderParamOcclusionQuery: 11,
            gviRenderParamOutlineColor: 12,
            gviRenderParamAlphaTestValue: 13,
            gviRenderParamClipPlaneLineColor: 14
        },
        gviManipulatorMode: {
            gviCityMakerManipulator: 0,
            gviGoogleEarthManipulator: 1
        },
        gviLengthUnit: {
            gviLengthUnitMeter: 0,
            gviLengthUnitKilometer: 1,
            gviLengthUnitFoot: 2,
            gviLengthUnitMile: 3,
            gviLengthUnitSeaMile: 4
        },
        gviAreaUnit: {
            gviAreaUnitSquareMeter: 0,
            gviAreaUnitSquareKilometer: 1,
            gviAreaUnitHectare: 2,
            gviAreaUnitMu: 3,
            gviAreaUnitQing: 4,
            gviAreaUnitAcre: 5,
            gviAreaUnitSquareMile: 6
        },
        gviLockMode: {
            gviLockDecal: 0,
            gviLockAxis: 1,
            gviLockAxisTextUp: 2,
            gviAxisAutoPitch: 3,
            gviAxisAutoPitchTextup: 4
        },
        gviDynamicMotionStyle: {
            gviDynamicMotionGroundVehicle: 0,
            gviDynamicMotionAirplane: 1,
            gviDynamicMotionHelicopter: 2,
            gviDynamicMotionHover: 3
        },
        gviElevationBehaviorMode: {
            gviElevationBehaviorReplace: 0,
            gviElevationBehaviorBelow: 1,
            gviElevationBehaviorAbove: 2
        },
        gviDepthTestMode: {
            gviDepthTestEnable: 0,
            gviDepthTestDisable: 1,
            gviDepthTestAdvance: 2,
            gviDepthTestGreaterEqual: 3,
            gviDepthTestGreater: 4,
            gviDepthTestLessEqual: 5,
            gviDepthTestEqual: 6,
            gviDepthTestNotEqual: 7,
            gviDepthTestAlways: 8,
            gviDepthTestAdvanceSecondDrawMaxDepth: 1000
        },
        gviWalkMode: {
            gviWalkDisable: 0,
            gviWalkOnWalkGround: 1,
            gviWalkOnAll: -1
        },
        gviTerrainActionCode: {
            gviFlyToTerrain: 0,
            gviJumpToTerrain: 1
        },
        gviAltitudeType: {
            gviAltitudeTerrainRelative: 0,
            gviAltitudePivotRelative: 1,
            gviAltitudeOnTerrain: 2,
            gviAltitudeTerrainAbsolute: 3
        },
        gviLineToGroundType: {
            gviLineTypeNone: 0,
            gviLineTypeToGround: 1,
            gviLineTypeCustom: 2
        },
        gviShowTextOptions: {
            gviShowTextAlways: 0,
            gviShowTextOnHover: 1
        },
        gviPresentationPlayMode: {
            gviPresentationPlayAutomatic: 0,
            gviPresentationPlayManual: 1
        },
        gviPresentationPlaySpeed: {
            gviPresentationPlayVerySlow: 0,
            gviPresentationPlaySlow: 1,
            gviPresentationPlayNormal: 2,
            gviPresentationPlayFast: 3,
            gviPresentationPlayVeryFast: 4
        },
        gviPresentationStatus: {
            gviPresentationPlaying: 0,
            gviPresentationNotPlaying: 1,
            gviPresentationPaused: 2,
            gviPresentationWaitingTime: 3,
            gviPresentationWaitingClick: 4,
            gviPresentationBeforeSwitchingToAnotherPresentation: 5,
            gviPresentationAfterSwitchingFromAnotherPresentation: 6
        },
        gviPresentationStepContinue: {
            gviPresentationStepContinueMouseClick: 0,
            gviPresentationStepContinueWait: 1
        },
        gviPresentationStepFlightSpeed: {
            gviPresentationStepFlightVerySlow: 0,
            gviPresentationStepFlightSlow: 1,
            gviPresentationStepFlightNormal: 2,
            gviPresentationStepFlightFast: 3,
            gviPresentationStepFlightVeryFast: 4
        },
        gviPresentationSplineSpeedBehavior: {
            gviPresentationSplineSpeedAutomatic: 0,
            gviPresentationSplineSpeedManualIgnoreSpeedFactor: 1,
            gviPresentationSplineSpeedManualWithSpeedFactor: 2
        },
        gviPresentationStepType: {
            gviPresentationStepTypeLocation: 0,
            gviPresentationStepTypeDynamicObject: 1,
            gviPresentationStepTypeGroupOrObject: 2,
            gviPresentationStepTypeUnderGroundMode: 3,
            gviPresentationStepTypeTimeSlider: 4,
            gviPresentationStepTypeSetTime: 5,
            gviPresentationStepTypeMessage: 6,
            gviPresentationStepTypeTool: 7,
            gviPresentationStepTypeCaption: 8,
            gviPresentationStepTypeRestartDynamicObject: 9,
            gviPresentationStepTypeFlightSpeedFactor: 10,
            gviPresentationStepTypePlayTimeAnimation: 11,
            gviPresentationStepTypePlayAnotherPresentation: 12,
            gviPresentationStepTypeObjectControl: 13,
            gviPresentationStepTypeEnvironmentSetting: 14,
            gviPresentationStepTypeClearCaption: -1
        },
        gviPresentationCaptionPosition: {
            gviPresentationCaptionPositionTopLeft: 0,
            gviPresentationCaptionPositionTopCenter: 1,
            gviPresentationCaptionPositionTopRight: 2,
            gviPresentationCaptionPositionBottomLeft: 3,
            gviPresentationCaptionPositionBottomCenter: 4,
            gviPresentationCaptionPositionBottomRight: 5
        },
        gviPresentationCaptionSizeType: {
            gviPresentationCaptionSizeTypeFixed: 0,
            gviPresentationCaptionSizeTypeAutomaticallyAdjust: 1
        },
        gviPresentationPlayAlgorithm: {
            gviPresentationPlayAlgorithmFlyTo: 0,
            gviPresentationPlayAlgorithmSpline: 1
        },
        gviComplexParticleEffectType: {
            gviComplexParticleEffectUnknown: 0,
            gviComplexParticleEffectFire_0: 1000,
            gviComplexParticleEffectFire_1: 1001,
            gviComplexParticleEffectFire_2: 1002,
            gviComplexParticleEffectFire_3: 1003,
            gviComplexParticleEffectFire_4: 1004,
            gviComplexParticleEffectSmoke_0: 2000,
            gviComplexParticleEffectSmoke_1: 2001,
            gviComplexParticleEffectSmoke_2: 2002,
            gviComplexParticleEffectExplosion_0: 3000,
            gviComplexParticleEffectExplosion_1: 3001,
            gviComplexParticleEffectExplosion_2: 3002,
            gviComplexParticleEffectExplosion_3: 3003,
            gviComplexParticleEffectExplosion_4: 3004,
            gviComplexParticleEffectExplosion_5: 3005,
            gviComplexParticleEffectExplosion_6: 3006,
            gviComplexParticleEffectExplosion_7: 3007,
            gviComplexParticleEffectExplosion_8: 3008,
            gviComplexParticleEffectRocketTailFlame: 9000
        },
        gviMsgChainFlags: {
            gviMsgChainLButtonDown: 1,
            gviMsgChainLButtonUp: 2,
            gviMsgChainLButtonDblClk: 4,
            gviMsgChainMButtonDown: 8,
            gviMsgChainMButtonUp: 16,
            gviMsgChainMButtonDblClk: 32,
            gviMsgChainRButtonDown: 64,
            gviMsgChainRButtonUp: 128,
            gviMsgChainRButtonDblClk: 256,
            gviMsgChainMouseMove: 512,
            gviMsgChainMouseHover: 1024,
            gviMsgChainMouseWheel: 2048,
            gviMsgChainKeyDown: 4096,
            gviMsgChainKeyUp: 8192
        },
        gviUIWindowType: {
            gviUIUnknown: 0,
            gviUIImageButton: 1,
            gviUIButton: 2
        },
        gviUIEventType: {
            gviUIMouseMove: -17,
            gviUIMouseButtonDoubleClick: -16,
            gviUIMouseButtonUp: -15,
            gviUIMouseButtonDown: -14,
            gviUIMouseLeavesArea: -13,
            gviUIMouseEntersArea: -12,
            gviUIMouseClick: -11,
            gviUINone: -1
        },
        gviUIMouseButtonType: {
            gviUILeftButton: 0,
            gviUIRightButton: 1,
            gviUIMiddleButton: 2,
            gviUIX1Button: 3,
            gviUIX2Button: 4,
            gviUIMouseButtonCount: 5,
            gviUINoButton: 6
        },
        gviImageType: {
            gviImageStatic: 0,
            gviImageDynamic: 1,
            gviImageCube: 2
        },
        gviImageFormat: {
            gviImageUnknown: 0,
            gviImageDDS: 1,
            gviImagePNG: 2,
            gviImageJPG: 3,
            gviImagePVR: 4
        },
        gviTextureWrapMode: {
            gviTextureWrapRepeat: 0,
            gviTextureWrapClampToEdge: 1
        },
        gviCullFaceMode: {
            gviCullNone: 0,
            gviCullBack: 1,
            gviCullFront: 2
        },
        gviPrimitiveType: {
            gviPrimitiveNormal: 0,
            gviPrimitiveBillboardZ: 1,
            gviPrimitiveWater: 2,
            gviPrimitiveGlass: 3,
            gviPrimitive3DTree: 4,
            gviPrimitiveNone: 5
        },
        gviPrimitiveMode: {
            gviPrimitiveModeTriangleList: 0,
            gviPrimitiveModeLineList: 1,
            gviPrimitiveModePointList: 2,
            gviPrimitiveModeNone: 3
        },
        gviModelType: {
            gviModelStatic: 1,
            gviModelSkinning: 2
        },
        gviTVDisplayMode: {
            gviTVShowPicture: 2,
            gviTVShowIcon: 4,
            gviTVShowEnvelopLines: 32,
            gviTVShowEnvelopFaces: 64,
            gviTVShowLinesFacesAndIcon: 100,
            gviTVShowLinesAndPicture: 34,
            gviTVShowAll: 65535
        }
    };
    if (typeof define === "function" && define.amd) {
        define("cm7", [], function () {
            return cm7;
        })
    }
    var _cm7 = window.cm7,
        _cm7Enum = window.cm7Enum,
        strundefined = typeof undefined;
    cm7.noConflict = function (deep) {
        if (deep && window.cm7 === cm7) {
            window.cm7 = _cm7;
            window.cm7Enum = _cm7Enum
        }
        return cm7;
    };
    if (typeof noGlobal === strundefined) {
        window.cm7 = cm7;
        window.cm7Enum = cm7Enum
    }
    return cm7;
}));